home *** CD-ROM | disk | FTP | other *** search
/ Aminet 16 / Aminet 16 (1996)(GTI - Schatztruhe)[!][Dec 1996].iso / Aminet / comm / term / term_source.lha / Extras / Source / term-source.lha / Config.c < prev    next >
C/C++ Source or Header  |  1996-10-20  |  71KB  |  3,168 lines

  1. /*
  2. **    Config.c
  3. **
  4. **    Configuration processing routines
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16.     /* Reset routine function pointer. */
  17.  
  18. typedef VOID (* RESET)(APTR,STRPTR);
  19.  
  20. /*****************************************************************************/
  21.  
  22.     /* Local routines. */
  23.  
  24. STATIC BOOL ReadSystemPrefs(STRPTR Name, ULONG ID, APTR Data, LONG Size, LONG Count);
  25. STATIC VOID ResetSerialConfig(struct SerialSettings *SerialConfig);
  26. STATIC VOID ResetModem(struct ModemSettings *ModemConfig);
  27. STATIC VOID ResetScreen(struct ScreenSettings *ScreenConfig);
  28. STATIC VOID ResetTerminal(struct TerminalSettings *TerminalConfig);
  29. STATIC VOID ResetEmulation(struct EmulationSettings *EmulationConfig);
  30. STATIC VOID ResetClip(struct ClipSettings *ClipConfig);
  31. STATIC VOID ResetCapture(struct CaptureSettings *CaptureConfig);
  32. STATIC VOID ResetTranslationFile(STRPTR Here, STRPTR PathBuffer);
  33. STATIC VOID ResetMacroFile(STRPTR Here, STRPTR PathBuffer);
  34. STATIC VOID ResetCursorFile(STRPTR Here, STRPTR PathBuffer);
  35. STATIC VOID ResetFastMacroFile(STRPTR Here, STRPTR PathBuffer);
  36. STATIC VOID ResetSpeechFile(STRPTR Here, STRPTR PathBuffer);
  37. STATIC VOID ResetSoundFile(STRPTR Here, STRPTR PathBuffer);
  38. STATIC VOID ResetAreaCodeFile(STRPTR Here, STRPTR PathBuffer);
  39. STATIC VOID ResetPhonebookFile(STRPTR Here, STRPTR PathBuffer);
  40. STATIC VOID ResetHotkeyFile(STRPTR Here, STRPTR PathBuffer);
  41. STATIC VOID ResetTrapFile(STRPTR Here, STRPTR PathBuffer);
  42. STATIC VOID ResetFile(struct FileSettings *FileConfig, STRPTR PathBuffer);
  43. STATIC VOID ResetPath(struct PathSettings *PathConfig, STRPTR PathBuffer);
  44. STATIC VOID ResetMisc(struct MiscSettings *MiscConfig);
  45. STATIC VOID ResetCommand(struct CommandSettings *UnusedCommandConfig);
  46. STATIC VOID ResetTransfer(struct TransferSettings *TransferConfig, STRPTR DefaultLib);
  47. STATIC VOID ResetNewConfigEntry(APTR To, LONG Type);
  48. STATIC BOOL WriteConfigChunk(struct IFFHandle *Handle, struct Configuration *LocalConfig, LONG Type, APTR TempBuffer, STRPTR Password);
  49. STATIC LONG IsConfigChunk(ULONG ID);
  50. STATIC BOOL WriteConfigChunks(struct IFFHandle *Handle, struct Configuration *LocalConfig, APTR TempBuffer, STRPTR Password);
  51. STATIC BOOL ClosePhonebookFile(struct IFFHandle *Handle);
  52. STATIC struct IFFHandle *CreatePhonebookFile(STRPTR Name, PhonebookHandle *PhoneHandle);
  53. STATIC BOOL DumpPhonebookRates(struct IFFHandle *Handle, struct PhoneEntry *Entry);
  54. STATIC BOOL DumpPhonebookGroups(struct IFFHandle *Handle, struct List *GroupList);
  55. STATIC BOOL DumpPhonebookFile(struct IFFHandle *Handle, APTR TempBuffer, PhonebookHandle *PhoneHandle);
  56. STATIC BOOL ReadConfigChunk(struct IFFHandle *Handle, struct Configuration *LocalConfig, LONG Type, LONG Len, STRPTR Password);
  57.  
  58. /*****************************************************************************/
  59.  
  60. STATIC BOOL                    FontPrefsRead        = FALSE,
  61.                             FontPrefsReadFailed    = FALSE;
  62. STATIC struct FontPrefs        FontPrefs[3];
  63.  
  64. /*****************************************************************************/
  65.  
  66. STATIC UWORD SizeTable[] =
  67. {
  68.     sizeof(struct SerialSettings),
  69.     sizeof(struct ModemSettings),
  70.     sizeof(struct CommandSettings),
  71.     sizeof(struct ScreenSettings),
  72.     sizeof(struct TerminalSettings),
  73.     sizeof(struct PathSettings),
  74.     sizeof(struct MiscSettings),
  75.     sizeof(struct ClipSettings),
  76.     sizeof(struct CaptureSettings),
  77.     sizeof(struct FileSettings),
  78.     sizeof(struct EmulationSettings),
  79.     sizeof(struct TransferSettings),
  80.     MAX_FILENAME_LENGTH,                /* Translation file name */
  81.     MAX_FILENAME_LENGTH,                /* Macro file name */
  82.     MAX_FILENAME_LENGTH,                /* Cursor file name */
  83.     MAX_FILENAME_LENGTH,                /* Fast macro file name */
  84.     MAX_FILENAME_LENGTH,                /* Speech file name */
  85.     MAX_FILENAME_LENGTH,                /* Sound file name */
  86.     MAX_FILENAME_LENGTH,                /* Area code file name */
  87.     MAX_FILENAME_LENGTH,                /* Phonebook file name */
  88.     MAX_FILENAME_LENGTH,                /* Hotkey file name */
  89.     MAX_FILENAME_LENGTH                    /* Trap file name */
  90. };
  91.  
  92. STATIC RESET ResetTable[] =
  93. {
  94.     (RESET)ResetSerialConfig,
  95.     (RESET)ResetModem,
  96.     (RESET)ResetCommand,
  97.     (RESET)ResetScreen,
  98.     (RESET)ResetTerminal,
  99.     (RESET)ResetPath,
  100.     (RESET)ResetMisc,
  101.     (RESET)ResetClip,
  102.     (RESET)ResetCapture,
  103.     (RESET)ResetFile,
  104.     (RESET)ResetEmulation,
  105.     (RESET)ResetTransfer,
  106.     (RESET)ResetTranslationFile,
  107.     (RESET)ResetMacroFile,
  108.     (RESET)ResetCursorFile,
  109.     (RESET)ResetFastMacroFile,
  110.     (RESET)ResetSpeechFile,
  111.     (RESET)ResetSoundFile,
  112.     (RESET)ResetAreaCodeFile,
  113.     (RESET)ResetPhonebookFile,
  114.     (RESET)ResetHotkeyFile,
  115.     (RESET)ResetTrapFile
  116. };
  117.  
  118. STATIC ULONG TypeTable[] =
  119. {
  120.     ID_SERL,
  121.     ID_MODM,
  122.     ID_COMD,
  123.     ID_SCRN,
  124.     ID_TRML,
  125.     ID_PATH,
  126.     ID_MISC,
  127.     ID_CLIP,
  128.     ID_CPTR,
  129.     ID_FILE,
  130.     ID_EMLN,
  131.     ID_XFER,
  132.     ID_XLNM,
  133.     ID_MFNM,
  134.     ID_CRNM,
  135.     ID_FMNM,
  136.     ID_SPNM,
  137.     ID_SONM,
  138.     ID_ACNM,
  139.     ID_PBNM,
  140.     ID_HKNM,
  141.     ID_TRNM
  142. };
  143.  
  144. #define NUM_STOPS (sizeof(Stops) / (2 * sizeof(ULONG)))
  145.  
  146. STATIC LONG Stops[] =
  147. {
  148.     ID_TERM,ID_CAT,
  149.     ID_TERM,ID_VERS,
  150.     ID_TERM,ID_DIAL,
  151.     ID_TERM,ID_DAT2,
  152.     ID_TERM,ID_DATE,
  153.     ID_TERM,ID_PHON,
  154.     ID_TERM,ID_PSWD,
  155.  
  156.     ID_TERM,ID_SERL,
  157.     ID_TERM,ID_MODM,
  158.     ID_TERM,ID_COMD,
  159.     ID_TERM,ID_SCRN,
  160.     ID_TERM,ID_TRML,
  161.     ID_TERM,ID_PATH,
  162.     ID_TERM,ID_MISC,
  163.     ID_TERM,ID_CLIP,
  164.     ID_TERM,ID_CPTR,
  165.     ID_TERM,ID_FILE,
  166.     ID_TERM,ID_EMLN,
  167.     ID_TERM,ID_XFER,
  168.     ID_TERM,ID_WINF,
  169.     ID_TERM,ID_GRUP,
  170.     ID_TERM,ID_XLNM,
  171.     ID_TERM,ID_MFNM,
  172.     ID_TERM,ID_CRNM,
  173.     ID_TERM,ID_FMNM,
  174.     ID_TERM,ID_SPNM,
  175.     ID_TERM,ID_SONM,
  176.     ID_TERM,ID_ACNM,
  177.     ID_TERM,ID_PBNM,
  178.     ID_TERM,ID_HKNM,
  179.     ID_TERM,ID_TRNM
  180. };
  181.  
  182. /*****************************************************************************/
  183.  
  184. enum    {    CR_IGNORE,CR_ASCR,CR_ASCRLF };
  185. enum    {    LF_IGNORE,LF_ASLF,LF_ASLFCR };
  186.  
  187. /*****************************************************************************/
  188.  
  189. VOID
  190. StripGlobals(struct Configuration *LocalConfig)
  191. {
  192.     if(LocalConfig)
  193.     {
  194.         FreeVecPooled(LocalConfig->SpeechFileName);
  195.         FreeVecPooled(LocalConfig->SoundFileName);
  196.         FreeVecPooled(LocalConfig->AreaCodeFileName);
  197.         FreeVecPooled(LocalConfig->PhonebookFileName);
  198.         FreeVecPooled(LocalConfig->HotkeyFileName);
  199.         FreeVecPooled(LocalConfig->TrapFileName);
  200.  
  201.         LocalConfig->SpeechFileName        = NULL;
  202.         LocalConfig->SoundFileName        = NULL;
  203.         LocalConfig->AreaCodeFileName    = NULL;
  204.         LocalConfig->PhonebookFileName    = NULL;
  205.         LocalConfig->HotkeyFileName        = NULL;
  206.         LocalConfig->TrapFileName        = NULL;
  207.     }
  208. }
  209.  
  210. VOID
  211. FinalFix(struct Configuration *LocalConfig,BOOL UnusedIsPhonebook,LONG Version,LONG Revision)
  212. {
  213.     if(LocalConfig)
  214.     {
  215.         if(Version < 4 || (Version == 4 && Revision < 3))
  216.         {
  217.             if(LocalConfig->TransferConfig && LocalConfig->MiscConfig)
  218.             {
  219.                 LocalConfig->TransferConfig->OverridePath    = LocalConfig->MiscConfig->OverridePath;
  220.                 LocalConfig->TransferConfig->SetArchivedBit    = LocalConfig->MiscConfig->SetArchivedBit;
  221.                 LocalConfig->TransferConfig->IdentifyFiles    = LocalConfig->MiscConfig->IdentifyFiles;
  222.                 LocalConfig->TransferConfig->TransferIcons    = LocalConfig->MiscConfig->TransferIcons;
  223.                 LocalConfig->TransferConfig->PerfMeter        = LocalConfig->MiscConfig->PerfMeter;
  224.                 LocalConfig->TransferConfig->HideUploadIcon    = LocalConfig->MiscConfig->HideUploadIcon;
  225.             }
  226.         }
  227.  
  228.         if(Version < 4 || (Version == 4 && Revision < 4))
  229.         {
  230.             if(LocalConfig->TerminalConfig && LocalConfig->MiscConfig)
  231.                 LocalConfig->MiscConfig->AlertMode = LocalConfig->TerminalConfig->AlertMode;
  232.         }
  233.     }
  234. }
  235.  
  236. VOID
  237. FixOldConfig(struct Configuration *LocalConfig,UBYTE ConfigChunkType,BOOL IsPhonebook,LONG Version,LONG Revision)
  238. {
  239.     if((Version == 3 && Revision < 6) || Version < 3)
  240.     {
  241.         if(ConfigChunkType == PREF_CLIP)
  242.             LocalConfig->ClipConfig->ConvertLF = TRUE;
  243.  
  244.         if(ConfigChunkType == PREF_SERIAL)
  245.             LocalConfig->SerialConfig->UseOwnDevUnit = TRUE;
  246.  
  247.         if(ConfigChunkType == PREF_MISC)
  248.             LocalConfig->MiscConfig->ProtectiveMode = TRUE;
  249.  
  250.         if(ConfigChunkType == PREF_SCREEN)
  251.         {
  252.             LocalConfig->ScreenConfig->UsePens            = TRUE;
  253.             LocalConfig->ScreenConfig->Depth            = 0;
  254.             LocalConfig->ScreenConfig->PenColourMode    = 42;    /* Avoid trouble */
  255.         }
  256.  
  257.         if(ConfigChunkType == PREF_TRANSFER)
  258.         {
  259.             LONG i;
  260.  
  261.             LocalConfig->TransferConfig->MangleFileNames = FALSE;
  262.  
  263.             if(LocalConfig->TransferConfig->ASCIIUploadLibrary[0])
  264.                 LocalConfig->TransferConfig->ASCIIUploadType = XFER_XPR;
  265.  
  266.             if(LocalConfig->TransferConfig->ASCIIDownloadLibrary[0])
  267.                 LocalConfig->TransferConfig->ASCIIDownloadType = XFER_XPR;
  268.  
  269.             if(LocalConfig->TransferConfig->TextUploadLibrary[0])
  270.                 LocalConfig->TransferConfig->TextUploadType = XFER_XPR;
  271.  
  272.             if(LocalConfig->TransferConfig->TextDownloadLibrary[0])
  273.                 LocalConfig->TransferConfig->TextDownloadType = XFER_XPR;
  274.  
  275.             if(LocalConfig->TransferConfig->BinaryUploadLibrary[0])
  276.                 LocalConfig->TransferConfig->BinaryUploadType = XFER_XPR;
  277.  
  278.             if(LocalConfig->TransferConfig->BinaryDownloadLibrary[0])
  279.                 LocalConfig->TransferConfig->BinaryDownloadType = XFER_XPR;
  280.  
  281.             for(i = 0 ; i < strlen(LocalConfig->TransferConfig->DefaultLibrary) - 6 ; i++)
  282.             {
  283.                 if(!Strnicmp(&LocalConfig->TransferConfig->DefaultLibrary[i],"zmodem",6))
  284.                 {
  285.                     strcpy(LocalConfig->TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Signature,"*\030B01");
  286.  
  287.                     LocalConfig->TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Length = strlen(LocalConfig->TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Signature);
  288.  
  289.                     break;
  290.                 }
  291.             }
  292.         }
  293.  
  294.         if(ConfigChunkType == PREF_MODEM)
  295.             LocalConfig->ModemConfig->AbortHangsUp = FALSE;
  296.  
  297.         if(ConfigChunkType == PREF_COMMAND && IsPhonebook)
  298.         {
  299.             strcpy(LocalConfig->CommandConfig->LoginMacro,LocalConfig->CommandConfig->StartupMacro);
  300.  
  301.             memset(LocalConfig->CommandConfig->StartupMacro,0,sizeof(LocalConfig->CommandConfig->StartupMacro));
  302.         }
  303.  
  304.         if(ConfigChunkType == PREF_CAPTURE)
  305.             LocalConfig->CaptureConfig->SearchHistory = 10;
  306.  
  307.         if(ConfigChunkType == PREF_EMULATION)
  308.         {
  309.             if(LocalConfig->EmulationConfig->DestructiveBackspace < 0 || LocalConfig->EmulationConfig->DestructiveBackspace > 2)
  310.                 LocalConfig->EmulationConfig->DestructiveBackspace = 1;
  311.         }
  312.     }
  313.  
  314.     if((Version == 4 && Revision < 1) || Version < 4)
  315.     {
  316.         if(ConfigChunkType == PREF_CLIP)
  317.             LocalConfig->ClipConfig->ConvertLF = TRUE;
  318.  
  319.         if(ConfigChunkType == PREF_SERIAL)
  320.         {
  321.             LocalConfig->SerialConfig->xONxOFF        = FALSE;
  322.             LocalConfig->SerialConfig->PassThrough    = TRUE;
  323.         }
  324.  
  325.         if(ConfigChunkType == PREF_MISC)
  326.             LocalConfig->MiscConfig->ProtectiveMode = TRUE;
  327.  
  328.         if(ConfigChunkType == PREF_MODEM)
  329.         {
  330.             LocalConfig->ModemConfig->RedialDelay    = (LocalConfig->ModemConfig->RedialDelay / 6) * 60 + (LocalConfig->ModemConfig->RedialDelay % 6) * 10;
  331.             LocalConfig->ModemConfig->TimeToConnect    = (LocalConfig->ModemConfig->TimeToConnect / 6) * 60 + (LocalConfig->ModemConfig->TimeToConnect % 6) * 10;
  332.             LocalConfig->ModemConfig->VerboseDialing    = FALSE;
  333.         }
  334.  
  335.         if(ConfigChunkType == PREF_TERMINAL)
  336.         {
  337.             switch(LocalConfig->TerminalConfig->SendCR)
  338.             {
  339.                 case CR_IGNORE:
  340.  
  341.                     LocalConfig->TerminalConfig->SendCR = EOL_IGNORE;
  342.                     break;
  343.  
  344.                 case CR_ASCR:
  345.  
  346.                     LocalConfig->TerminalConfig->SendCR = EOL_CR;
  347.                     break;
  348.  
  349.                 case CR_ASCRLF:
  350.  
  351.                     LocalConfig->TerminalConfig->SendCR = EOL_CRLF;
  352.                     break;
  353.             }
  354.  
  355.             switch(LocalConfig->TerminalConfig->ReceiveCR)
  356.             {
  357.                 case CR_IGNORE:
  358.  
  359.                     LocalConfig->TerminalConfig->ReceiveCR = EOL_IGNORE;
  360.                     break;
  361.  
  362.                 case CR_ASCR:
  363.  
  364.                     LocalConfig->TerminalConfig->ReceiveCR = EOL_CR;
  365.                     break;
  366.  
  367.                 case CR_ASCRLF:
  368.  
  369.                     LocalConfig->TerminalConfig->ReceiveCR = EOL_CRLF;
  370.                     break;
  371.             }
  372.  
  373.             switch(LocalConfig->TerminalConfig->SendLF)
  374.             {
  375.                 case LF_IGNORE:
  376.  
  377.                     LocalConfig->TerminalConfig->SendLF = EOL_IGNORE;
  378.                     break;
  379.  
  380.                 case LF_ASLF:
  381.  
  382.                     LocalConfig->TerminalConfig->SendLF = EOL_LF;
  383.                     break;
  384.  
  385.                 case LF_ASLFCR:
  386.  
  387.                     LocalConfig->TerminalConfig->SendLF = EOL_LFCR;
  388.                     break;
  389.             }
  390.  
  391.             switch(LocalConfig->TerminalConfig->ReceiveLF)
  392.             {
  393.                 case LF_IGNORE:
  394.  
  395.                     LocalConfig->TerminalConfig->ReceiveLF = EOL_IGNORE;
  396.                     break;
  397.  
  398.                 case LF_ASLF:
  399.  
  400.                     LocalConfig->TerminalConfig->ReceiveLF = EOL_LF;
  401.                     break;
  402.  
  403.                 case LF_ASLFCR:
  404.  
  405.                     LocalConfig->TerminalConfig->ReceiveLF = EOL_LFCR;
  406.                     break;
  407.             }
  408.         }
  409.  
  410.         if(ConfigChunkType == PREF_TRANSFER)
  411.         {
  412.             LONG i;
  413.  
  414.             if(LocalConfig->TransferConfig->ASCIIUploadLibrary[0])
  415.                 LocalConfig->TransferConfig->ASCIIUploadType = XFER_XPR;
  416.  
  417.             if(LocalConfig->TransferConfig->ASCIIDownloadLibrary[0])
  418.                 LocalConfig->TransferConfig->ASCIIDownloadType = XFER_XPR;
  419.  
  420.             if(LocalConfig->TransferConfig->TextUploadLibrary[0])
  421.                 LocalConfig->TransferConfig->TextUploadType = XFER_XPR;
  422.  
  423.             if(LocalConfig->TransferConfig->TextDownloadLibrary[0])
  424.                 LocalConfig->TransferConfig->TextDownloadType = XFER_XPR;
  425.  
  426.             if(LocalConfig->TransferConfig->BinaryUploadLibrary[0])
  427.                 LocalConfig->TransferConfig->BinaryUploadType = XFER_XPR;
  428.  
  429.             if(LocalConfig->TransferConfig->BinaryDownloadLibrary[0])
  430.                 LocalConfig->TransferConfig->BinaryDownloadType = XFER_XPR;
  431.  
  432.             for(i = 0 ; i < strlen(LocalConfig->TransferConfig->DefaultLibrary) - 6 ; i++)
  433.             {
  434.                 if(!Strnicmp(&LocalConfig->TransferConfig->DefaultLibrary[i],"zmodem",6))
  435.                 {
  436.                     strcpy(LocalConfig->TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Signature,"*\030B01");
  437.  
  438.                     LocalConfig->TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Length = strlen(LocalConfig->TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Signature);
  439.  
  440.                     break;
  441.                 }
  442.             }
  443.  
  444.             switch(LocalConfig->TransferConfig->SendCR)
  445.             {
  446.                 case CR_IGNORE:
  447.  
  448.                     LocalConfig->TransferConfig->SendCR = EOL_IGNORE;
  449.                     break;
  450.  
  451.                 case CR_ASCR:
  452.  
  453.                     LocalConfig->TransferConfig->SendCR = EOL_CR;
  454.                     break;
  455.  
  456.                 case CR_ASCRLF:
  457.  
  458.                     LocalConfig->TransferConfig->SendCR = EOL_CRLF;
  459.                     break;
  460.             }
  461.  
  462.             switch(LocalConfig->TransferConfig->ReceiveCR)
  463.             {
  464.                 case CR_IGNORE:
  465.  
  466.                     LocalConfig->TransferConfig->ReceiveCR = EOL_IGNORE;
  467.                     break;
  468.  
  469.                 case CR_ASCR:
  470.  
  471.                     LocalConfig->TransferConfig->ReceiveCR = EOL_CR;
  472.                     break;
  473.  
  474.                 case CR_ASCRLF:
  475.  
  476.                     LocalConfig->TransferConfig->ReceiveCR = EOL_CRLF;
  477.                     break;
  478.             }
  479.  
  480.             switch(LocalConfig->TransferConfig->SendLF)
  481.             {
  482.                 case LF_IGNORE:
  483.  
  484.                     LocalConfig->TransferConfig->SendLF = EOL_IGNORE;
  485.                     break;
  486.  
  487.                 case LF_ASLF:
  488.  
  489.                     LocalConfig->TransferConfig->SendLF = EOL_LF;
  490.                     break;
  491.  
  492.                 case LF_ASLFCR:
  493.  
  494.                     LocalConfig->TransferConfig->SendLF = EOL_LFCR;
  495.                     break;
  496.             }
  497.  
  498.             switch(LocalConfig->TransferConfig->ReceiveLF)
  499.             {
  500.                 case LF_IGNORE:
  501.  
  502.                     LocalConfig->TransferConfig->ReceiveLF = EOL_IGNORE;
  503.                     break;
  504.  
  505.                 case LF_ASLF:
  506.  
  507.                     LocalConfig->TransferConfig->ReceiveLF = EOL_LF;
  508.                     break;
  509.  
  510.                 case LF_ASLFCR:
  511.  
  512.                     LocalConfig->TransferConfig->ReceiveLF = EOL_LFCR;
  513.                     break;
  514.             }
  515.         }
  516.     }
  517.  
  518.     if(Version == 4 && Revision < 3)
  519.     {
  520.         if(ConfigChunkType == PREF_CLIP)
  521.             LocalConfig->ClipConfig->ConvertLF = TRUE;
  522.  
  523.         if(ConfigChunkType == PREF_SERIAL)
  524.         {
  525.             LocalConfig->SerialConfig->xONxOFF        = FALSE;
  526.             LocalConfig->SerialConfig->PassThrough    = TRUE;
  527.         }
  528.  
  529.         if(ConfigChunkType == PREF_MISC)
  530.             LocalConfig->MiscConfig->ProtectiveMode = TRUE;
  531.  
  532.         if(ConfigChunkType == PREF_TRANSFER)
  533.         {
  534.             LONG i;
  535.  
  536.             for(i = 0 ; i < strlen(LocalConfig->TransferConfig->DefaultLibrary) - 6 ; i++)
  537.             {
  538.                 if(!Strnicmp(&LocalConfig->TransferConfig->DefaultLibrary[i],"zmodem",6))
  539.                 {
  540.                     strcpy(LocalConfig->TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Signature,"*\030B01");
  541.  
  542.                     LocalConfig->TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Length = strlen(LocalConfig->TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Signature);
  543.  
  544.                     break;
  545.                 }
  546.             }
  547.  
  548.             if(LocalConfig->TransferConfig->ASCIIUploadLibrary[0])
  549.                 LocalConfig->TransferConfig->ASCIIUploadType = XFER_XPR;
  550.  
  551.             if(LocalConfig->TransferConfig->ASCIIDownloadLibrary[0])
  552.                 LocalConfig->TransferConfig->ASCIIDownloadType = XFER_XPR;
  553.  
  554.             if(LocalConfig->TransferConfig->InternalASCIIUpload)
  555.                 LocalConfig->TransferConfig->ASCIIUploadType = XFER_INTERNAL;
  556.  
  557.             if(LocalConfig->TransferConfig->InternalASCIIDownload)
  558.                 LocalConfig->TransferConfig->ASCIIDownloadType = XFER_INTERNAL;
  559.  
  560.             if(LocalConfig->TransferConfig->TextUploadLibrary[0])
  561.                 LocalConfig->TransferConfig->TextUploadType = XFER_XPR;
  562.  
  563.             if(LocalConfig->TransferConfig->TextDownloadLibrary[0])
  564.                 LocalConfig->TransferConfig->TextDownloadType = XFER_XPR;
  565.  
  566.             if(LocalConfig->TransferConfig->BinaryUploadLibrary[0])
  567.                 LocalConfig->TransferConfig->BinaryUploadType = XFER_XPR;
  568.  
  569.             if(LocalConfig->TransferConfig->BinaryDownloadLibrary[0])
  570.                 LocalConfig->TransferConfig->BinaryDownloadType = XFER_XPR;
  571.         }
  572.     }
  573. }
  574.  
  575. VOID
  576. FixScreenPens(struct ScreenSettings *ScreenConfig)
  577. {
  578.     LONG i,Count;
  579.  
  580.     for(Count = 0, i = DETAILPEN ; i <= BARTRIMPEN ; i++)
  581.     {
  582.         if(ScreenConfig->PenArray[i])
  583.             Count++;
  584.     }
  585.  
  586.     if(!Count)
  587.         ScreenConfig->UsePens = TRUE;
  588. }
  589.  
  590. /*****************************************************************************/
  591.  
  592.     /* ReadSystemPrefs():
  593.      *
  594.      *    Reads the system preferences settings.
  595.      */
  596.  
  597. STATIC BOOL
  598. ReadSystemPrefs(STRPTR Name,ULONG ID,APTR Data,LONG Size,LONG Count)
  599. {
  600.     struct IFFHandle *Handle;
  601.     LONG Error;
  602.  
  603.         /* Allocate an IFF handle. */
  604.  
  605.     if(Handle = OpenIFFStream(Name,MODE_OLDFILE))
  606.     {
  607.             /* Stop at the `body' chunk. */
  608.  
  609.         if(!(Error = StopChunk(Handle,ID_PREF,ID)))
  610.         {
  611.                 /* Look for it... */
  612.  
  613.             while(!ParseIFF(Handle,IFFPARSE_SCAN))
  614.             {
  615.                     /* Read the data. */
  616.  
  617.                 if(ReadChunkBytes(Handle,Data,Size) == Size)
  618.                 {
  619.                     if(Count)
  620.                     {
  621.                         Count--;
  622.  
  623.                         Data = (APTR)((ULONG)Data + Size);
  624.                     }
  625.                     else
  626.                         break;
  627.                 }
  628.                 else
  629.                 {
  630.                     Error = IoErr();
  631.  
  632.                     break;
  633.                 }
  634.             }
  635.         }
  636.  
  637.             /* Close the handle. */
  638.  
  639.         CloseIFFStream(Handle);
  640.     }
  641.     else
  642.         Error = IoErr();
  643.  
  644.         /* Return sucess/failure. */
  645.  
  646.     if(Error)
  647.     {
  648.         SetIoErr(Error);
  649.  
  650.         return(FALSE);
  651.     }
  652.     else
  653.         return(TRUE);
  654. }
  655.  
  656. /*****************************************************************************/
  657.  
  658. STATIC VOID
  659. ResetSerialConfig(struct SerialSettings *SerialConfig)
  660. {
  661.     STATIC BOOL                    SerialPrefsRead            = FALSE,
  662.                                 SerialPrefsReadFailed    = FALSE;
  663.     STATIC struct SerialPrefs    SerialPrefs;
  664.  
  665.         /* The program will only try to read the preferences
  666.          * settings once; if the first access failed, no
  667.          * other accesses will be made.
  668.          */
  669.  
  670.     if(!SerialPrefsRead && !SerialPrefsReadFailed)
  671.     {
  672.         if(!ReadSystemPrefs("ENV:sys/serial.prefs",ID_SERL,&SerialPrefs,sizeof(SerialPrefs),1))
  673.             SerialPrefsReadFailed = TRUE;
  674.  
  675.         SerialPrefsRead = TRUE;
  676.     }
  677.  
  678.         /* Did we succeed in reading the file? */
  679.  
  680.     if(SerialPrefsRead && !SerialPrefsReadFailed)
  681.     {
  682.             /* Fill in the common data. */
  683.  
  684.         SerialConfig->BaudRate            = SerialPrefs.sp_BaudRate;
  685.         SerialConfig->SerialBufferSize    = SerialPrefs.sp_InputBuffer;
  686.         SerialConfig->BitsPerChar        = SerialPrefs.sp_BitsPerChar;
  687.         SerialConfig->StopBits            = SerialPrefs.sp_StopBits;
  688.  
  689.             /* Convert the handshaking mode. */
  690.  
  691.         switch(SerialPrefs.sp_InputHandshake)
  692.         {
  693.             case HSHAKE_NONE:
  694.  
  695.                 SerialConfig->HandshakingProtocol = HANDSHAKING_NONE;
  696.  
  697.                 break;
  698.  
  699.             case HSHAKE_RTS:
  700.  
  701.                 SerialConfig->HandshakingProtocol = HANDSHAKING_RTSCTS_DSR;
  702.  
  703.                 break;
  704.  
  705.             default:
  706.  
  707.                 SerialConfig->HandshakingProtocol = HANDSHAKING_NONE;
  708.  
  709.                 break;
  710.         }
  711.  
  712.             /* Convert the parity settings. */
  713.  
  714.         if(SerialPrefs.sp_Parity <= PARITY_SPACE)
  715.             SerialConfig->Parity = SerialPrefs.sp_Parity;
  716.         else
  717.             SerialConfig->Parity = PARITY_NONE;
  718.     }
  719.     else
  720.     {
  721.         SerialConfig->BaudRate                = 19200;
  722.         SerialConfig->BitsPerChar            = 8;
  723.         SerialConfig->Parity                = PARITY_NONE;
  724.         SerialConfig->StopBits                = 1;
  725.         SerialConfig->HandshakingProtocol    = HANDSHAKING_RTSCTS_DSR;
  726.         SerialConfig->SerialBufferSize        = 32768;
  727.     }
  728.  
  729.     strcpy(SerialConfig->SerialDevice,SERIALNAME);
  730.  
  731.     SerialConfig->Duplex                = DUPLEX_FULL;
  732.     SerialConfig->BreakLength            = 250000;
  733.     SerialConfig->UnitNumber            = 0;
  734.     SerialConfig->PassThrough            = TRUE;
  735.  
  736.     SerialConfig->Quantum                = 256;
  737.  
  738.     SerialConfig->SatisfyODURequests    = ODU_RELEASE;
  739. }
  740.  
  741. STATIC VOID
  742. ResetModem(struct ModemSettings *ModemConfig)
  743. {
  744.     strcpy(ModemConfig->ModemInit,            "ATX3E1V1Q0\\r");
  745.     strcpy(ModemConfig->ModemExit,            "");
  746.     strcpy(ModemConfig->ModemHangup,        "~~~~+++~~~~ATH0\\r");
  747.     strcpy(ModemConfig->DialPrefix,            "ATD\\w");
  748.     strcpy(ModemConfig->DialSuffix,            "\\r");
  749.  
  750.     strcpy(ModemConfig->NoCarrier,            "NO CARRIER");
  751.     strcpy(ModemConfig->NoDialTone,            "NO DIALTONE");
  752.     strcpy(ModemConfig->Connect,            "CONNECT");
  753.     strcpy(ModemConfig->Voice,                "VOICE");
  754.     strcpy(ModemConfig->Ring,                "RING");
  755.     strcpy(ModemConfig->Busy,                "BUSY");
  756.     strcpy(ModemConfig->Ok,                    "OK");
  757.     strcpy(ModemConfig->Error,                "ERROR");
  758.  
  759.     ModemConfig->RedialDelay                = 20;
  760.     ModemConfig->DialRetries                = 10;
  761.     ModemConfig->DialTimeout                = 60;
  762.  
  763.     ModemConfig->NoCarrierIsBusy            = TRUE;
  764.  
  765.     ModemConfig->DialMode                    = DIALMODE_PULSE;
  766.  
  767.     strcpy(ModemConfig->PBX_Prefix,            "0,,,");
  768. }
  769.  
  770. STATIC VOID
  771. ResetScreen(struct ScreenSettings *ScreenConfig)
  772. {
  773.     struct Screen *PubScreen;
  774.     ULONG DisplayID;
  775.  
  776.     if(!FontPrefsRead && !FontPrefsReadFailed)
  777.     {
  778.         if(!ReadSystemPrefs("ENV:sys/font.prefs",ID_FONT,FontPrefs,sizeof(struct FontPrefs),3))
  779.             FontPrefsReadFailed = TRUE;
  780.  
  781.         FontPrefsRead = TRUE;
  782.     }
  783.  
  784.     DisplayID = INVALID_ID;
  785.  
  786.     strcpy(ScreenConfig->FontName,"topaz.font");
  787.     ScreenConfig->FontHeight = 8;
  788.  
  789.     if(FontPrefsRead && !FontPrefsReadFailed)
  790.     {
  791.         LONG i;
  792.  
  793.         for(i = 0 ; i < 3 ; i++)
  794.         {
  795.             if(FontPrefs[i].fp_Type == FP_SCREENFONT)
  796.             {
  797.                 strcpy(ScreenConfig->FontName,FontPrefs[i].fp_Name);
  798.                 ScreenConfig->FontHeight = FontPrefs[i].fp_TextAttr.ta_YSize;
  799.  
  800.                 break;
  801.             }
  802.         }
  803.     }
  804.  
  805.     if(DisplayID == INVALID_ID)
  806.     {
  807.         if(PubScreen = LockPubScreen(NULL))
  808.         {
  809.             DisplayID = GetVPModeID(&PubScreen->ViewPort);
  810.  
  811.             UnlockPubScreen(NULL,PubScreen);
  812.         }
  813.         else
  814.             DisplayID = DEFAULT_MONITOR_ID | HIRESLACE_KEY;
  815.     }
  816.  
  817.     ScreenConfig->DisplayMode        = DisplayID;
  818.     ScreenConfig->ColourMode        = COLOUR_AMIGA;
  819.     ScreenConfig->MakeScreenPublic    = TRUE;
  820.     ScreenConfig->TitleBar            = TRUE;
  821.     ScreenConfig->StatusLine        = STATUSLINE_STANDARD;
  822.     ScreenConfig->Blinking            = TRUE;
  823.     ScreenConfig->FasterLayout        = TRUE;
  824.  
  825.     ScreenConfig->TimeMode            = ONLINETIME_BOTH;
  826.     ScreenConfig->UsePens            = TRUE;
  827.     ScreenConfig->PenColourMode        = COLOUR_AMIGA;
  828.  
  829.     ScreenConfig->OverscanType        = OSCAN_TEXT;
  830. }
  831.  
  832. STATIC VOID
  833. ResetTerminal(struct TerminalSettings *TerminalConfig)
  834. {
  835.     if(!FontPrefsRead && !FontPrefsReadFailed)
  836.     {
  837.         if(!ReadSystemPrefs("ENV:sys/font.prefs",ID_FONT,FontPrefs,sizeof(struct FontPrefs),3))
  838.             FontPrefsReadFailed = TRUE;
  839.  
  840.         FontPrefsRead = TRUE;
  841.     }
  842.  
  843.     strcpy(TerminalConfig->TextFontName,"topaz.font");
  844.     TerminalConfig->TextFontHeight = 8;
  845.  
  846.     strcpy(TerminalConfig->IBMFontName,"IBM.font");
  847.     TerminalConfig->IBMFontHeight = 8;
  848.  
  849.     if(FontPrefsRead && !FontPrefsReadFailed)
  850.     {
  851.         LONG i;
  852.  
  853.         for(i = 0 ; i < 3 ; i++)
  854.         {
  855.             if(FontPrefs[i].fp_Type == FP_SYSFONT)
  856.             {
  857.                 strcpy(TerminalConfig->TextFontName,FontPrefs[i].fp_Name);
  858.                 TerminalConfig->TextFontHeight = FontPrefs[i].fp_TextAttr.ta_YSize;
  859.  
  860.                 if(TerminalConfig->TextFontHeight == 8 || TerminalConfig->TextFontHeight == 11)
  861.                     TerminalConfig->IBMFontHeight = TerminalConfig->TextFontHeight;
  862.  
  863.                 break;
  864.             }
  865.         }
  866.     }
  867.  
  868.     TerminalConfig->BellMode        = BELL_AUDIBLE;
  869.     TerminalConfig->AlertMode        = ALERT_BEEP_SCREEN;
  870.     TerminalConfig->EmulationMode    = EMULATION_ANSIVT100;
  871.     TerminalConfig->FontMode        = FONT_STANDARD;
  872.  
  873.     TerminalConfig->SendCR            = EOL_CR;
  874.     TerminalConfig->SendLF            = EOL_LF;
  875.     TerminalConfig->ReceiveCR        = EOL_CR;
  876.     TerminalConfig->ReceiveLF        = EOL_LF;
  877. }
  878.  
  879. STATIC VOID
  880. ResetEmulation(struct EmulationSettings *EmulationConfig)
  881. {
  882.     LONG i;
  883.  
  884.     EmulationConfig->CursorMode            = KEYMODE_STANDARD;
  885.     EmulationConfig->NumericMode        = KEYMODE_STANDARD;
  886.  
  887.     EmulationConfig->LineWrap            = TRUE;
  888.  
  889.     EmulationConfig->FontScale            = SCALE_NORMAL;
  890.     EmulationConfig->ScrollMode            = SCROLL_JUMP;
  891.     EmulationConfig->PrinterEnabled        = TRUE;
  892.     EmulationConfig->MaxJump            = 1;
  893.  
  894.     EmulationConfig->UseStandardPens    = TRUE;
  895.  
  896.     for(i = TEXTATTR_UNDERLINE ; i <= TEXTATTR_INVERSE ; i++)
  897.         EmulationConfig->Attributes[i] = i;
  898.  
  899.     for(i = 0 ; i < 16 ; i++)
  900.         EmulationConfig->Pens[i] = i;
  901.  
  902.     EmulationConfig->TerminalType = TERMINAL_VT200;
  903. }
  904.  
  905. STATIC VOID
  906. ResetClip(struct ClipSettings *ClipConfig)
  907. {
  908.     strcpy(ClipConfig->InsertSuffix,"\\r");
  909.  
  910.     ClipConfig->PacingMode        = PACE_DIRECT;
  911.     ClipConfig->ConvertLF        = TRUE;
  912. }
  913.  
  914. STATIC VOID
  915. ResetCapture(struct CaptureSettings *CaptureConfig)
  916. {
  917.     CaptureConfig->BufferEnabled        = TRUE;
  918.  
  919.     CaptureConfig->CaptureFilterMode    = FILTER_BOTH;
  920.  
  921.     CaptureConfig->AutoCaptureDate        = AUTOCAPTURE_DATE_NAME;
  922.     CaptureConfig->SearchHistory        = 10;
  923.  
  924.     CaptureConfig->OpenBufferWindow        = BUFFER_END;
  925.     CaptureConfig->OpenBufferScreen        = BUFFER_TOP;
  926.     CaptureConfig->BufferScreenPosition    = SCREEN_CENTRE;
  927.     CaptureConfig->BufferWidth            = 80;
  928.  
  929.     CaptureConfig->BufferScreenMode        = INVALID_ID;
  930.  
  931.     CaptureConfig->BufferMode            = BUFFERMODE_FLOW;
  932.  
  933.     CaptureConfig->LogFileFormat        = LOGFILEFORMAT_CallInfo;
  934.  
  935.     CaptureConfig->BufferSafetyMemory    = 60 * 1024;
  936. }
  937.  
  938. STATIC VOID
  939. ResetTranslationFile(STRPTR Here,STRPTR PathBuffer)
  940. {
  941.     if(!PathBuffer)
  942.         PathBuffer = "TERM:config";
  943.  
  944.     if(!LastTranslation[0])
  945.     {
  946.         strcpy(LastTranslation,PathBuffer);
  947.  
  948.         AddPart(LastTranslation,"translation.prefs",MAX_FILENAME_LENGTH);
  949.     }
  950.  
  951.     strcpy(Here,LastTranslation);
  952. }
  953.  
  954. STATIC VOID
  955. ResetMacroFile(STRPTR Here,STRPTR PathBuffer)
  956. {
  957.     if(!PathBuffer)
  958.         PathBuffer = "TERM:config";
  959.  
  960.     if(!LastMacros[0])
  961.     {
  962.         strcpy(LastMacros,PathBuffer);
  963.  
  964.         AddPart(LastMacros,"functionkeys.prefs",MAX_FILENAME_LENGTH);
  965.     }
  966.  
  967.     strcpy(Here,LastMacros);
  968. }
  969.  
  970. STATIC VOID
  971. ResetCursorFile(STRPTR Here,STRPTR PathBuffer)
  972. {
  973.     if(!PathBuffer)
  974.         PathBuffer = "TERM:config";
  975.  
  976.     if(!LastCursorKeys[0])
  977.     {
  978.         strcpy(LastCursorKeys,PathBuffer);
  979.  
  980.         AddPart(LastCursorKeys,"cursorkeys.prefs",MAX_FILENAME_LENGTH);
  981.     }
  982.  
  983.     strcpy(Here,LastCursorKeys);
  984. }
  985.  
  986. STATIC VOID
  987. ResetFastMacroFile(STRPTR Here,STRPTR PathBuffer)
  988. {
  989.     if(!PathBuffer)
  990.         PathBuffer = "TERM:config";
  991.  
  992.     if(!LastFastMacros[0])
  993.     {
  994.         strcpy(LastFastMacros,PathBuffer);
  995.  
  996.         AddPart(LastFastMacros,"fastmacros.prefs",MAX_FILENAME_LENGTH);
  997.     }
  998.  
  999.     strcpy(Here,LastFastMacros);
  1000. }
  1001.  
  1002. STATIC VOID
  1003. ResetSpeechFile(STRPTR Here,STRPTR PathBuffer)
  1004. {
  1005.     if(!PathBuffer)
  1006.         PathBuffer = "TERM:config";
  1007.  
  1008.     if(!LastSpeech[0])
  1009.     {
  1010.         strcpy(LastSpeech,PathBuffer);
  1011.  
  1012.         AddPart(LastSpeech,"speech.prefs",MAX_FILENAME_LENGTH);
  1013.     }
  1014.  
  1015.     strcpy(Here,LastSpeech);
  1016. }
  1017.  
  1018. STATIC VOID
  1019. ResetSoundFile(STRPTR Here,STRPTR PathBuffer)
  1020. {
  1021.     if(!PathBuffer)
  1022.         PathBuffer = "TERM:config";
  1023.  
  1024.     if(!LastSound[0])
  1025.     {
  1026.         strcpy(LastSound,PathBuffer);
  1027.  
  1028.         AddPart(LastSound,"sound.prefs",MAX_FILENAME_LENGTH);
  1029.     }
  1030.  
  1031.     strcpy(Here,LastSound);
  1032. }
  1033.  
  1034. STATIC VOID
  1035. ResetAreaCodeFile(STRPTR Here,STRPTR PathBuffer)
  1036. {
  1037.     if(!PathBuffer)
  1038.         PathBuffer = "TERM:config";
  1039.  
  1040.     if(!LastPattern[0])
  1041.     {
  1042.         strcpy(LastPattern,PathBuffer);
  1043.  
  1044.         AddPart(LastPattern,"rates.prefs",MAX_FILENAME_LENGTH);
  1045.     }
  1046.  
  1047.     strcpy(Here,LastPattern);
  1048. }
  1049.  
  1050. STATIC VOID
  1051. ResetPhonebookFile(STRPTR Here,STRPTR PathBuffer)
  1052. {
  1053.     if(!PathBuffer)
  1054.         PathBuffer = "TERM:config";
  1055.  
  1056.     if(!LastPhone[0])
  1057.     {
  1058.         strcpy(LastPhone,PathBuffer);
  1059.  
  1060.         AddPart(LastPhone,"phonebook.prefs",MAX_FILENAME_LENGTH);
  1061.     }
  1062.  
  1063.     strcpy(Here,LastPhone);
  1064. }
  1065.  
  1066. STATIC VOID
  1067. ResetHotkeyFile(STRPTR Here,STRPTR PathBuffer)
  1068. {
  1069.     if(!PathBuffer)
  1070.         PathBuffer = "TERM:config";
  1071.  
  1072.     if(!LastKeys[0])
  1073.     {
  1074.         strcpy(LastKeys,PathBuffer);
  1075.  
  1076.         AddPart(LastKeys,"hotkeys.prefs",MAX_FILENAME_LENGTH);
  1077.     }
  1078.  
  1079.     strcpy(Here,LastKeys);
  1080. }
  1081.  
  1082. STATIC VOID
  1083. ResetTrapFile(STRPTR Here,STRPTR PathBuffer)
  1084. {
  1085.     if(!PathBuffer)
  1086.         PathBuffer = "TERM:config";
  1087.  
  1088.     if(!LastTraps[0])
  1089.     {
  1090.         strcpy(LastTraps,PathBuffer);
  1091.  
  1092.         AddPart(LastTraps,"trap.prefs",MAX_FILENAME_LENGTH);
  1093.     }
  1094.  
  1095.     strcpy(Here,LastTraps);
  1096. }
  1097.  
  1098. STATIC VOID
  1099. ResetFile(struct FileSettings *FileConfig,STRPTR PathBuffer)
  1100. {
  1101.     if(!PathBuffer)
  1102.         PathBuffer = "TERM:config";
  1103.  
  1104.     strcpy(FileConfig->ProtocolFileName,"xprzmodem.library");
  1105.  
  1106.     if(!LastTranslation[0])
  1107.     {
  1108.         strcpy(LastTranslation,PathBuffer);
  1109.  
  1110.         AddPart(LastTranslation,"translation.prefs",MAX_FILENAME_LENGTH);
  1111.     }
  1112.  
  1113.     strcpy(FileConfig->TranslationFileName,LastTranslation);
  1114.  
  1115.     if(!LastMacros[0])
  1116.     {
  1117.         strcpy(LastMacros,PathBuffer);
  1118.  
  1119.         AddPart(LastMacros,"functionkeys.prefs",MAX_FILENAME_LENGTH);
  1120.     }
  1121.  
  1122.     strcpy(FileConfig->MacroFileName,LastMacros);
  1123.  
  1124.     if(!LastFastMacros[0])
  1125.     {
  1126.         strcpy(LastFastMacros,PathBuffer);
  1127.  
  1128.         AddPart(LastFastMacros,"fastmacros.prefs",MAX_FILENAME_LENGTH);
  1129.     }
  1130.  
  1131.     strcpy(FileConfig->FastMacroFileName,LastFastMacros);
  1132.  
  1133.     if(!LastCursorKeys[0])
  1134.     {
  1135.         strcpy(LastCursorKeys,PathBuffer);
  1136.  
  1137.         AddPart(LastCursorKeys,"cursorkeys.prefs",MAX_FILENAME_LENGTH);
  1138.     }
  1139.  
  1140.     strcpy(FileConfig->CursorFileName,LastCursorKeys);
  1141. }
  1142.  
  1143. STATIC VOID
  1144. ResetPath(struct PathSettings *PathConfig,STRPTR PathBuffer)
  1145. {
  1146.     if(!PathBuffer)
  1147.         PathBuffer = "TERM:config";
  1148.  
  1149.     strcpy(PathConfig->DefaultStorage,PathBuffer);
  1150.  
  1151.     strcpy(PathConfig->HelpFile,"PROGDIR:term.guide");
  1152.  
  1153.     strcpy(PathConfig->DefaultStorage,PathBuffer);
  1154.  
  1155.     GetEnvDOS("EDITOR",PathConfig->Editor,sizeof(PathConfig->Editor));
  1156. }
  1157.  
  1158. STATIC VOID
  1159. ResetMisc(struct MiscSettings *MiscConfig)
  1160. {
  1161.     MiscConfig->Priority            = 1;
  1162.  
  1163.     MiscConfig->ReleaseDevice        = TRUE;
  1164.  
  1165.     MiscConfig->TransferServer        = TRUE;
  1166.     MiscConfig->EmulationServer        = TRUE;
  1167.  
  1168.     MiscConfig->OverridePath        = TRUE;
  1169.     MiscConfig->AutoUpload            = TRUE;
  1170.     MiscConfig->IdentifyFiles        = IDENTIFY_FILETYPE;
  1171.  
  1172.     MiscConfig->IOBufferSize        = 32768;
  1173.  
  1174.     MiscConfig->ProtectiveMode        = TRUE;
  1175.  
  1176.     MiscConfig->AlertMode            = ALERT_BEEP_SCREEN;
  1177.     MiscConfig->RequesterMode        = REQUESTERMODE_IGNORE;
  1178.  
  1179.     strcpy(MiscConfig->WaitString," \\b");
  1180.  
  1181.     MiscConfig->WaitDelay            = 1;    /* Just one second */
  1182.  
  1183.     if(!GetEnvDOS("TERMWINDOW",MiscConfig->WindowName,sizeof(MiscConfig->WindowName)))
  1184.         strcpy(MiscConfig->WindowName,"CON:0/11//100/term Output Window/CLOSE/SCREEN %s");
  1185. }
  1186.  
  1187. STATIC VOID
  1188. ResetCommand(struct CommandSettings *UnusedCommandConfig)
  1189. {
  1190. }
  1191.  
  1192. STATIC VOID
  1193. ResetTransfer(struct TransferSettings *TransferConfig,STRPTR DefaultLib)
  1194. {
  1195.     LONG i;
  1196.  
  1197.     if(!DefaultLib)
  1198.         strcpy(TransferConfig->DefaultLibrary,"xprzmodem.library");
  1199.     else
  1200.         strcpy(TransferConfig->DefaultLibrary,DefaultLib);
  1201.  
  1202.     for(i = 0 ; i < strlen(TransferConfig->DefaultLibrary) - 6 ; i++)
  1203.     {
  1204.         if(!Strnicmp(&TransferConfig->DefaultLibrary[i],"zmodem",6))
  1205.         {
  1206.             strcpy(TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Signature,"*\030B01");
  1207.  
  1208.             TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Length = strlen(TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Signature);
  1209.  
  1210.             break;
  1211.         }
  1212.     }
  1213.  
  1214.     strcpy(TransferConfig->ASCIIUploadLibrary,        "xprascii.library");
  1215.     strcpy(TransferConfig->ASCIIDownloadLibrary,    "xprascii.library");
  1216.  
  1217.     strcpy(TransferConfig->BinaryUploadLibrary,"run hydracom device %p speed %b line %c nocarrier rec %> send %m");
  1218.     strcpy(TransferConfig->BinaryDownloadLibrary,"run hydracom device %p speed %b line %c nocarrier rec %> get");
  1219.  
  1220.     TransferConfig->PacingMode                = PACE_DIRECT;
  1221.     TransferConfig->IgnoreDataPastArnold    = TRUE;
  1222.     TransferConfig->TerminatorChar            = 0x1A;
  1223.     TransferConfig->SendCR                    = EOL_CR;
  1224.     TransferConfig->SendLF                    = EOL_LF;
  1225.     TransferConfig->ReceiveCR                = EOL_CR;
  1226.     TransferConfig->ReceiveLF                = EOL_LF;
  1227.  
  1228.     TransferConfig->ErrorNotification        = 20;
  1229.     TransferConfig->TransferNotification    = XFERNOTIFY_ALWAYS;
  1230.  
  1231.     TransferConfig->DefaultType                = XFER_XPR;
  1232.     TransferConfig->ASCIIDownloadType        = XFER_XPR;
  1233.     TransferConfig->ASCIIUploadType            = XFER_XPR;
  1234.     TransferConfig->TextDownloadType        = XFER_DEFAULT;
  1235.     TransferConfig->TextUploadType            = XFER_DEFAULT;
  1236.     TransferConfig->BinaryDownloadType        = XFER_DEFAULT;
  1237.     TransferConfig->BinaryUploadType        = XFER_DEFAULT;
  1238.  
  1239.     TransferConfig->OverridePath            = TRUE;
  1240.     TransferConfig->IdentifyFiles            = IDENTIFY_FILETYPE;
  1241. }
  1242.  
  1243. /*****************************************************************************/
  1244.  
  1245. STATIC BOOL
  1246. WriteConfigChunk(struct IFFHandle *Handle,struct Configuration *LocalConfig,LONG Type,APTR TempBuffer,STRPTR Password)
  1247. {
  1248.     if(Type >= PREF_SERIAL && Type < PREF_RATES && Type != PREF_FILE)
  1249.     {
  1250.         APTR Data;
  1251.         LONG Error;
  1252.  
  1253.         if(Data = GetConfigEntry(LocalConfig,Type))
  1254.         {
  1255.             if(TempBuffer)
  1256.             {
  1257.                 Encrypt(Data,SizeTable[Type - PREF_SERIAL],TempBuffer,Password,MAX_PASSWORD_LENGTH);
  1258.  
  1259.                 Data = TempBuffer;
  1260.             }
  1261.  
  1262.             if(!(Error = PushChunk(Handle,0,TypeTable[Type - PREF_SERIAL],SizeTable[Type - PREF_SERIAL])))
  1263.             {
  1264.                 if(WriteChunkRecords(Handle,Data,SizeTable[Type - PREF_SERIAL],1) != 1)
  1265.                     return(FALSE);
  1266.  
  1267.                 if(!(Error = PopChunk(Handle)))
  1268.                     return(TRUE);
  1269.             }
  1270.  
  1271.             SetIoErr(Error);
  1272.  
  1273.             return(FALSE);
  1274.         }
  1275.     }
  1276.  
  1277.     return(TRUE);
  1278. }
  1279.  
  1280. STATIC LONG
  1281. IsConfigChunk(ULONG ID)
  1282. {
  1283.     LONG Type;
  1284.  
  1285.     for(Type = PREF_SERIAL ; Type < PREF_RATES ; Type++)
  1286.     {
  1287.         if(ID == TypeTable[Type - PREF_SERIAL])
  1288.             return(Type);
  1289.     }
  1290.  
  1291.     return(0);
  1292. }
  1293.  
  1294. STATIC BOOL
  1295. WriteConfigChunks(struct IFFHandle *Handle,struct Configuration *LocalConfig,APTR TempBuffer,STRPTR Password)
  1296. {
  1297.     LONG Type;
  1298.  
  1299.     for(Type = PREF_SERIAL ; Type < PREF_RATES ; Type++)
  1300.     {
  1301.         if(!WriteConfigChunk(Handle,LocalConfig,Type,TempBuffer,Password))
  1302.             return(FALSE);
  1303.     }
  1304.  
  1305.     return(TRUE);
  1306. }
  1307.  
  1308. STATIC VOID
  1309. ResetNewConfigEntry(APTR To,LONG Type)
  1310. {
  1311.     if(Type >= PREF_SERIAL && Type < PREF_RATES)
  1312.     {
  1313.         LONG Size;
  1314.         APTR From;
  1315.  
  1316.         From = GetConfigEntry(Config,Type);
  1317.         Size = SizeTable[Type - PREF_SERIAL];
  1318.  
  1319.         if(From)
  1320.             CopyMem(From,To,Size);
  1321.         else
  1322.         {
  1323.             memset(To,0,Size);
  1324.  
  1325.             (*ResetTable[Type - PREF_SERIAL])(To,NULL);
  1326.         }
  1327.  
  1328.         if(Type == PREF_SCREEN)
  1329.             FixScreenPens(To);
  1330.     }
  1331. }
  1332.  
  1333. STATIC BOOL
  1334. ClosePhonebookFile(struct IFFHandle *Handle)
  1335. {
  1336.     LONG Error;
  1337.  
  1338.     Error = PopChunk(Handle);
  1339.  
  1340.     if(!CloseIFFStream(Handle))
  1341.     {
  1342.         if(!Error)
  1343.             Error = IoErr();
  1344.     }
  1345.  
  1346.     if(Error)
  1347.     {
  1348.         SetIoErr(Error);
  1349.  
  1350.         return(FALSE);
  1351.     }
  1352.     else
  1353.         return(TRUE);
  1354. }
  1355.  
  1356. STATIC struct IFFHandle *
  1357. CreatePhonebookFile(STRPTR Name,PhonebookHandle *PhoneHandle)
  1358. {
  1359.     struct IFFHandle *Handle;
  1360.  
  1361.     if(Handle = OpenIFFStream(Name,MODE_NEWFILE))
  1362.     {
  1363.         LONG Error;
  1364.  
  1365.         if(!(Error = PushChunk(Handle,ID_TERM,ID_CAT,IFFSIZE_UNKNOWN)))
  1366.         {
  1367.             if(!(Error = PushChunk(Handle,ID_TERM,ID_FORM,IFFSIZE_UNKNOWN)))
  1368.             {
  1369.                 if(!(Error = PushChunk(Handle,0,ID_VERS,sizeof(struct TermInfo))))
  1370.                 {
  1371.                     struct TermInfo TermInfo;
  1372.  
  1373.                     TermInfo.Version    = CONFIG_FILE_VERSION;
  1374.                     TermInfo.Revision    = CONFIG_FILE_REVISION;
  1375.  
  1376.                     if(WriteChunkRecords(Handle,&TermInfo,sizeof(struct TermInfo),1) != 1)
  1377.                         Error = IoErr();
  1378.                     else
  1379.                         Error = PopChunk(Handle);
  1380.                 }
  1381.  
  1382.                 if(!Error && PhoneHandle->PhonePasswordUsed)
  1383.                 {
  1384.                     if(!(Error = PushChunk(Handle,0,ID_PSWD,MAX_PASSWORD_LENGTH)))
  1385.                     {
  1386.                         if(WriteChunkBytes(Handle,PhoneHandle->PhonePassword,MAX_PASSWORD_LENGTH) != MAX_PASSWORD_LENGTH)
  1387.                             Error = IoErr();
  1388.                         else
  1389.                             Error = PopChunk(Handle);
  1390.                     }
  1391.                 }
  1392.  
  1393.                 if(!Error)
  1394.                 {
  1395.                     if(!(Error = PushChunk(Handle,0,ID_DIAL,sizeof(PhonebookGlobals))))
  1396.                     {
  1397.                         PhonebookGlobals Globals;
  1398.  
  1399.                         Globals.Count            = PhoneHandle->NumPhoneEntries;
  1400.                         Globals.ID                = PhoneHandle->PhonebookID;
  1401.                         Globals.DefaultGroup    = PhoneHandle->DefaultGroup;
  1402.                         Globals.AutoDial        = PhoneHandle->AutoDial;
  1403.                         Globals.AutoExit        = PhoneHandle->AutoExit;
  1404.  
  1405.                         if(WriteChunkBytes(Handle,&Globals,sizeof(Globals)) != sizeof(Globals))
  1406.                             Error = IoErr();
  1407.                         else
  1408.                             Error = PopChunk(Handle);
  1409.                     }
  1410.                 }
  1411.  
  1412.                 if(!Error)
  1413.                     Error = PopChunk(Handle);
  1414.             }
  1415.         }
  1416.  
  1417.         if(Error)
  1418.         {
  1419.             CloseIFFStream(Handle);
  1420.             DeleteFile(Name);
  1421.  
  1422.             SetIoErr(Error);
  1423.  
  1424.             return(NULL);
  1425.         }
  1426.         else
  1427.             return(Handle);
  1428.     }
  1429.     else
  1430.         return(NULL);
  1431. }
  1432.  
  1433. STATIC BOOL
  1434. DumpPhonebookRates(struct IFFHandle *Handle,struct PhoneEntry *Entry)
  1435. {
  1436.     struct TimeDateNode *TimeDateNode;
  1437.     LONG Error;
  1438.  
  1439.     Error = 0;
  1440.  
  1441.     for(TimeDateNode = (struct TimeDateNode *)Entry->TimeDateList.mlh_Head ; !Error && TimeDateNode->Node.ln_Succ ; TimeDateNode = (struct TimeDateNode *)TimeDateNode->Node.ln_Succ)
  1442.     {
  1443.         if(!(Error = PushChunk(Handle,0,ID_DAT2,IFFSIZE_UNKNOWN)))
  1444.         {
  1445.             if(WriteChunkBytes(Handle,&TimeDateNode->Header,sizeof(struct TimeDateHeader)) != sizeof(struct TimeDateHeader))
  1446.                 return(FALSE);
  1447.             else
  1448.             {
  1449.                 if(WriteChunkBytes(Handle,TimeDateNode->Table,TimeDateNode->Table[0].Count * sizeof(struct TimeDate)) != TimeDateNode->Table[0].Count * sizeof(struct TimeDate))
  1450.                     return(FALSE);
  1451.             }
  1452.  
  1453.             Error = PopChunk(Handle);
  1454.         }
  1455.     }
  1456.  
  1457.     if(Error)
  1458.     {
  1459.         SetIoErr(Error);
  1460.  
  1461.         return(FALSE);
  1462.     }
  1463.     else
  1464.         return(TRUE);
  1465. }
  1466.  
  1467. STATIC BOOL
  1468. DumpPhonebookGroups(struct IFFHandle *Handle,struct List *GroupList)
  1469. {
  1470.     if(!IsListEmpty(GroupList))
  1471.     {
  1472.         struct PhoneGroupNode *GroupNode;
  1473.         struct PhoneNode *Node;
  1474.         PhoneGroupHeader Header;
  1475.         BOOL FormOpen;
  1476.         LONG Error;
  1477.  
  1478.         FormOpen = FALSE;
  1479.  
  1480.             /* So the extension stuff is set to zero */
  1481.  
  1482.         memset(&Header,0,sizeof(Header));
  1483.  
  1484.             /* Run down the groups */
  1485.  
  1486.         for(GroupNode = (PhoneGroupNode *)GroupList->lh_Head ; GroupNode->Node.ln_Succ ; GroupNode = (PhoneGroupNode *)GroupNode->Node.ln_Succ)
  1487.         {
  1488.                 /* Count the members */
  1489.  
  1490.             Header.Count = GetListSize((struct List *)&GroupNode->GroupList);
  1491.  
  1492.                 /* Open the group */
  1493.  
  1494.             if(Header.Count > 0)
  1495.             {
  1496.                 if(!FormOpen)
  1497.                 {
  1498.                     if(Error = PushChunk(Handle,ID_TERM,ID_FORM,IFFSIZE_UNKNOWN))
  1499.                     {
  1500.                         SetIoErr(Error);
  1501.  
  1502.                         return(FALSE);
  1503.                     }
  1504.  
  1505.                     FormOpen = TRUE;
  1506.                 }
  1507.  
  1508.                     /* Pick up the group name */
  1509.  
  1510.                 strcpy(Header.FullName,GroupNode->LocalName);
  1511.  
  1512.                 if(Error = PushChunk(Handle,0,ID_GRUP,sizeof(Header) + sizeof(LONG) * Header.Count))
  1513.                 {
  1514.                     SetIoErr(Error);
  1515.  
  1516.                     return(FALSE);
  1517.                 }
  1518.                 else
  1519.                 {
  1520.                         /* First the header... */
  1521.  
  1522.                     if(WriteChunkBytes(Handle,&Header,sizeof(Header)) == sizeof(Header))
  1523.                     {
  1524.                             /* ...then the IDs of the group members */
  1525.  
  1526.                         for(Node = (struct PhoneNode *)GroupNode->GroupList.mlh_Head ; Node->Node.ln_Succ ; Node = (struct PhoneNode *)Node->Node.ln_Succ)
  1527.                         {
  1528.                             if(WriteChunkBytes(Handle,&Node->Entry->Header->ID,sizeof(ULONG)) != sizeof(ULONG))
  1529.                                 return(FALSE);
  1530.                         }
  1531.                     }
  1532.                     else
  1533.                         return(FALSE);
  1534.  
  1535.                     if(Error = PopChunk(Handle))
  1536.                     {
  1537.                         SetIoErr(Error);
  1538.  
  1539.                         return(FALSE);
  1540.                     }
  1541.                 }
  1542.             }
  1543.         }
  1544.  
  1545.         if(FormOpen)
  1546.         {
  1547.             if(Error = PopChunk(Handle))
  1548.             {
  1549.                 SetIoErr(Error);
  1550.  
  1551.                 return(FALSE);
  1552.             }
  1553.         }
  1554.     }
  1555.  
  1556.     return(TRUE);
  1557. }
  1558.  
  1559. STATIC BOOL
  1560. DumpPhonebookFile(struct IFFHandle *Handle,APTR TempBuffer,PhonebookHandle *PhoneHandle)
  1561. {
  1562.     PhoneEntry **Phonebook;
  1563.     STRPTR Password;
  1564.     APTR Whatever;
  1565.     APTR Stuff;
  1566.     LONG Error;
  1567.     LONG i;
  1568.  
  1569.     Error = 0;
  1570.  
  1571.     if(TempBuffer)
  1572.     {
  1573.         Password    = PhoneHandle->PhonePassword;
  1574.         Stuff        = TempBuffer;
  1575.     }
  1576.     else
  1577.     {
  1578.         Password    = NULL;
  1579.         Stuff        = NULL;
  1580.     }
  1581.  
  1582.     Phonebook = PhoneHandle->Phonebook;
  1583.  
  1584.     for(i = 0 ; !Error && i < PhoneHandle->NumPhoneEntries ; i++)
  1585.     {
  1586.         if(!(Error = PushChunk(Handle,ID_TERM,ID_FORM,IFFSIZE_UNKNOWN)))
  1587.         {
  1588.             if(!(Error = PushChunk(Handle,0,ID_PHON,sizeof(PhoneHeader))))
  1589.             {
  1590.                     /* New feature for v4.7: store the dialing order in the phoneheader. */
  1591.  
  1592.                 if(Phonebook[i]->Count < 0)
  1593.                     Phonebook[i]->Header->Marked = 0;
  1594.                 else
  1595.                     Phonebook[i]->Header->Marked = Phonebook[i]->Count + 1;
  1596.  
  1597.                 if(TempBuffer)
  1598.                 {
  1599.                     Encrypt((UBYTE *)Phonebook[i]->Header,sizeof(PhoneHeader),TempBuffer,PhoneHandle->PhonePassword,MAX_PASSWORD_LENGTH);
  1600.  
  1601.                     Whatever = TempBuffer;
  1602.                 }
  1603.                 else
  1604.                     Whatever = Phonebook[i]->Header;
  1605.  
  1606.                 if(WriteChunkRecords(Handle,Whatever,sizeof(PhoneHeader),1) != 1)
  1607.                     return(FALSE);
  1608.  
  1609.                 Error = PopChunk(Handle);
  1610.             }
  1611.  
  1612.             if(!Error)
  1613.             {
  1614.                 if(WriteConfigChunks(Handle,Phonebook[i]->Config,Stuff,Password))
  1615.                 {
  1616.                     if(!Phonebook[i]->Header->NoRates)
  1617.                     {
  1618.                         if(!DumpPhonebookRates(Handle,Phonebook[i]))
  1619.                             return(FALSE);
  1620.                     }
  1621.                 }
  1622.                 else
  1623.                     return(FALSE);
  1624.             }
  1625.  
  1626.             if(!Error)
  1627.                 Error = PopChunk(Handle);
  1628.         }
  1629.     }
  1630.  
  1631.         /* Now for the groups */
  1632.  
  1633.     if(!Error)
  1634.     {
  1635.         if(!DumpPhonebookGroups(Handle,(struct List *)&PhoneHandle->PhoneGroupList))
  1636.             Error = IoErr();
  1637.     }
  1638.  
  1639.     if(Error)
  1640.     {
  1641.         SetIoErr(Error);
  1642.         return(FALSE);
  1643.     }
  1644.     else
  1645.         return(TRUE);
  1646. }
  1647.  
  1648. STATIC BOOL
  1649. ReadConfigChunk(struct IFFHandle *Handle,struct Configuration *LocalConfig,LONG Type,LONG Len,STRPTR Password)
  1650. {
  1651.     if(CreateConfigEntry(LocalConfig,Type))
  1652.     {
  1653.         APTR Data;
  1654.  
  1655.         Data = GetConfigEntry(LocalConfig,Type);
  1656.  
  1657.         Len = MIN(SizeTable[Type - PREF_SERIAL],Len);
  1658.  
  1659.         if(ReadChunkBytes(Handle,Data,Len) == Len)
  1660.         {
  1661.             if(Password)
  1662.                 Decrypt(Data,Len,Data,Password,MAX_PASSWORD_LENGTH);
  1663.  
  1664.             if(Type == PREF_SCREEN)
  1665.                 FixScreenPens(Data);
  1666.  
  1667.             return(TRUE);
  1668.         }
  1669.     }
  1670.  
  1671.     return(FALSE);
  1672. }
  1673.  
  1674. STATIC APTR *
  1675. GetConfigEntryPointer(struct Configuration *LocalConfig,LONG Type)
  1676. {
  1677.     APTR *Mem;
  1678.  
  1679.     switch(Type)
  1680.     {
  1681.         case PREF_SERIAL:
  1682.  
  1683.             Mem = (APTR *)&LocalConfig->SerialConfig;
  1684.             break;
  1685.  
  1686.         case PREF_MODEM:
  1687.  
  1688.             Mem = (APTR *)&LocalConfig->ModemConfig;
  1689.             break;
  1690.  
  1691.         case PREF_COMMAND:
  1692.  
  1693.             Mem = (APTR *)&LocalConfig->CommandConfig;
  1694.             break;
  1695.  
  1696.         case PREF_SCREEN:
  1697.  
  1698.             Mem = (APTR *)&LocalConfig->ScreenConfig;
  1699.             break;
  1700.  
  1701.         case PREF_TERMINAL:
  1702.  
  1703.             Mem = (APTR *)&LocalConfig->TerminalConfig;
  1704.             break;
  1705.  
  1706.         case PREF_PATH:
  1707.  
  1708.             Mem = (APTR *)&LocalConfig->PathConfig;
  1709.             break;
  1710.  
  1711.         case PREF_MISC:
  1712.  
  1713.             Mem = (APTR *)&LocalConfig->MiscConfig;
  1714.             break;
  1715.  
  1716.         case PREF_CLIP:
  1717.  
  1718.             Mem = (APTR *)&LocalConfig->ClipConfig;
  1719.             break;
  1720.  
  1721.         case PREF_CAPTURE:
  1722.  
  1723.             Mem = (APTR *)&LocalConfig->CaptureConfig;
  1724.             break;
  1725.  
  1726.         case PREF_FILE:
  1727.  
  1728.             Mem = (APTR *)&LocalConfig->FileConfig;
  1729.             break;
  1730.  
  1731.         case PREF_EMULATION:
  1732.  
  1733.             Mem = (APTR *)&LocalConfig->EmulationConfig;
  1734.             break;
  1735.  
  1736.         case PREF_TRANSFER:
  1737.  
  1738.             Mem = (APTR *)&LocalConfig->TransferConfig;
  1739.             break;
  1740.  
  1741.         case PREF_TRANSLATIONFILENAME:
  1742.  
  1743.             Mem = (APTR *)&LocalConfig->TranslationFileName;
  1744.             break;
  1745.  
  1746.         case PREF_MACROFILENAME:
  1747.  
  1748.             Mem = (APTR *)&LocalConfig->MacroFileName;
  1749.             break;
  1750.  
  1751.         case PREF_CURSORFILENAME:
  1752.  
  1753.             Mem = (APTR *)&LocalConfig->CursorFileName;
  1754.             break;
  1755.  
  1756.         case PREF_FASTMACROFILENAME:
  1757.  
  1758.             Mem = (APTR *)&LocalConfig->FastMacroFileName;
  1759.             break;
  1760.  
  1761.         case PREF_SPEECHFILENAME:
  1762.  
  1763.             Mem = (APTR *)&LocalConfig->SpeechFileName;
  1764.             break;
  1765.  
  1766.         case PREF_SOUNDFILENAME:
  1767.  
  1768.             Mem = (APTR *)&LocalConfig->SoundFileName;
  1769.             break;
  1770.  
  1771.         case PREF_AREACODEFILENAME:
  1772.  
  1773.             Mem = (APTR *)&LocalConfig->AreaCodeFileName;
  1774.             break;
  1775.  
  1776.         case PREF_PHONEBOOKFILENAME:
  1777.  
  1778.             Mem = (APTR *)&LocalConfig->PhonebookFileName;
  1779.             break;
  1780.  
  1781.         case PREF_HOTKEYFILENAME:
  1782.  
  1783.             Mem = (APTR *)&LocalConfig->HotkeyFileName;
  1784.             break;
  1785.  
  1786.         case PREF_TRAPFILENAME:
  1787.  
  1788.             Mem = (APTR *)&LocalConfig->TrapFileName;
  1789.             break;
  1790.  
  1791.         default:
  1792.  
  1793.             Mem = NULL;
  1794.             break;
  1795.     }
  1796.  
  1797.     return(Mem);
  1798. }
  1799.  
  1800.     /* ResetConfig():
  1801.      *
  1802.      *    Initialize configuration with default values.
  1803.      */
  1804.  
  1805. VOID
  1806. ResetConfig(struct Configuration *LocalConfig,STRPTR PathBuffer)
  1807. {
  1808.     STRPTR Arg;
  1809.     LONG Type;
  1810.     APTR Data;
  1811.  
  1812.     if(!PathBuffer)
  1813.         PathBuffer = "TERM:config";
  1814.  
  1815.     for(Type = PREF_SERIAL ; Type < PREF_RATES ; Type++)
  1816.     {
  1817.         if(Data = GetConfigEntry(LocalConfig,Type))
  1818.         {
  1819.             memset(Data,0,SizeTable[Type - PREF_SERIAL]);
  1820.  
  1821.             switch(Type)
  1822.             {
  1823.                 case PREF_PATH:
  1824.                 case PREF_FILE:
  1825.                 case PREF_TRANSLATIONFILENAME:
  1826.                 case PREF_MACROFILENAME:
  1827.                 case PREF_CURSORFILENAME:
  1828.                 case PREF_FASTMACROFILENAME:
  1829.                 case PREF_SPEECHFILENAME:
  1830.                 case PREF_SOUNDFILENAME:
  1831.                 case PREF_AREACODEFILENAME:
  1832.                 case PREF_PHONEBOOKFILENAME:
  1833.                 case PREF_HOTKEYFILENAME:
  1834.                 case PREF_TRAPFILENAME:
  1835.  
  1836.                     Arg = PathBuffer;
  1837.                     break;
  1838.  
  1839.                 case PREF_TRANSFER:
  1840.  
  1841.                     if(LocalConfig->FileConfig)
  1842.                         Arg = LocalConfig->FileConfig->ProtocolFileName;
  1843.                     else
  1844.                         Arg = "xprzmodem.library";
  1845.  
  1846.                     break;
  1847.  
  1848.                 default:
  1849.  
  1850.                     Arg = NULL;
  1851.                     break;
  1852.             }
  1853.  
  1854.             (*ResetTable[Type - PREF_SERIAL])(Data,Arg);
  1855.         }
  1856.     }
  1857. }
  1858.  
  1859. VOID
  1860. DeleteConfigEntry(struct Configuration *LocalConfig,LONG Type)
  1861. {
  1862.     if(Type == PREF_ALL)
  1863.     {
  1864.         for(Type = PREF_SERIAL ; Type < PREF_RATES ; Type++)
  1865.             DeleteConfigEntry(LocalConfig,Type);
  1866.     }
  1867.     else
  1868.     {
  1869.         APTR *Mem;
  1870.  
  1871.         if(Mem = GetConfigEntryPointer(LocalConfig,Type))
  1872.         {
  1873.             FreeVecPooled(*Mem);
  1874.  
  1875.             *Mem = NULL;
  1876.         }
  1877.     }
  1878. }
  1879.  
  1880. VOID
  1881. ResetConfigEntry(struct Configuration *LocalConfig,LONG Type)
  1882. {
  1883.     if(LocalConfig && Type >= PREF_SERIAL && Type < PREF_RATES)
  1884.     {
  1885.         APTR To;
  1886.  
  1887.         if(To = GetConfigEntry(LocalConfig,Type))
  1888.             ResetNewConfigEntry(To,Type);
  1889.     }
  1890. }
  1891.  
  1892. APTR
  1893. GetConfigEntry(struct Configuration *LocalConfig,LONG Type)
  1894. {
  1895.     if(LocalConfig)
  1896.     {
  1897.         APTR *Mem;
  1898.  
  1899.         if(Mem = GetConfigEntryPointer(LocalConfig,Type))
  1900.             return(*Mem);
  1901.     }
  1902.  
  1903.     return(NULL);
  1904. }
  1905.  
  1906. LONG
  1907. CompareConfigEntries(APTR a,APTR b,LONG Type)
  1908. {
  1909.     LONG Result;
  1910.  
  1911.     if(Type < PREF_SERIAL || Type >= PREF_RATES || a == b)
  1912.         Result = 0;
  1913.     else
  1914.         Result = memcmp(a,b,SizeTable[Type - PREF_SERIAL]);
  1915.  
  1916.     return(Result);
  1917. }
  1918.  
  1919. VOID
  1920. PutConfigEntry(struct Configuration *LocalConfig,APTR Data,LONG Type)
  1921. {
  1922.     if(LocalConfig && Data && Type >= PREF_SERIAL && Type < PREF_RATES)
  1923.     {
  1924.         APTR Destination;
  1925.  
  1926.         if(Destination = GetConfigEntry(LocalConfig,Type))
  1927.         {
  1928.             if(Data != Destination)
  1929.                 CopyMem(Data,Destination,SizeTable[Type - PREF_SERIAL]);
  1930.         }
  1931.     }
  1932. }
  1933.  
  1934. VOID
  1935. CopyConfigEntry(struct Configuration *LocalConfig,LONG Type,APTR Data)
  1936. {
  1937.     if(LocalConfig && Data && Type >= PREF_SERIAL && Type < PREF_RATES)
  1938.     {
  1939.         APTR Source;
  1940.  
  1941.         if(Source = GetConfigEntry(LocalConfig,Type))
  1942.         {
  1943.             if(Source != Data)
  1944.                 CopyMem(Source,Data,SizeTable[Type - PREF_SERIAL]);
  1945.         }
  1946.     }
  1947. }
  1948.  
  1949. APTR
  1950. CreateNewConfigEntry(LONG Type)
  1951. {
  1952.     APTR Data;
  1953.  
  1954.     Data = NULL;
  1955.  
  1956.     if(Type >= PREF_SERIAL && Type < PREF_RATES)
  1957.     {
  1958.         if(Data = AllocVecPooled(SizeTable[Type - PREF_SERIAL],MEMF_ANY | MEMF_CLEAR))
  1959.             ResetNewConfigEntry(Data,Type);
  1960.     }
  1961.  
  1962.     return(Data);
  1963. }
  1964.  
  1965. BOOL
  1966. CreateConfigEntry(struct Configuration *LocalConfig,LONG Type)
  1967. {
  1968.     if(Type == PREF_ALL)
  1969.     {
  1970.         for(Type = PREF_SERIAL ; Type < PREF_RATES ; Type++)
  1971.         {
  1972.             if(!CreateConfigEntry(LocalConfig,Type))
  1973.             {
  1974.                 DeleteConfigEntry(LocalConfig,PREF_ALL);
  1975.                 return(FALSE);
  1976.             }
  1977.         }
  1978.  
  1979.         return(TRUE);
  1980.     }
  1981.     else
  1982.     {
  1983.         if(Type >= PREF_SERIAL && Type < PREF_RATES)
  1984.         {
  1985.             APTR *Mem;
  1986.  
  1987.             if(Mem = GetConfigEntryPointer(LocalConfig,Type))
  1988.             {
  1989.                 if(*Mem)
  1990.                     return(TRUE);
  1991.                 else
  1992.                 {
  1993.                     if(*Mem = CreateNewConfigEntry(Type))
  1994.                         return(TRUE);
  1995.                 }
  1996.             }
  1997.         }
  1998.  
  1999.         return(FALSE);
  2000.     }
  2001. }
  2002.  
  2003. VOID
  2004. DeleteConfiguration(struct Configuration *LocalConfig)
  2005. {
  2006.     if(LocalConfig)
  2007.     {
  2008.         DeleteConfigEntry(LocalConfig,PREF_ALL);
  2009.  
  2010.         FreeVecPooled(LocalConfig);
  2011.     }
  2012. }
  2013.  
  2014. struct Configuration *
  2015. CreateConfiguration(BOOL Fill)
  2016. {
  2017.     struct Configuration *LocalConfig;
  2018.  
  2019.     if(LocalConfig = (struct Configuration *)AllocVecPooled(sizeof(struct Configuration),MEMF_ANY | MEMF_CLEAR))
  2020.     {
  2021.         if(Fill)
  2022.         {
  2023.             if(!CreateConfigEntry(LocalConfig,PREF_ALL))
  2024.             {
  2025.                 FreeVecPooled(LocalConfig);
  2026.  
  2027.                 return(NULL);
  2028.             }
  2029.         }
  2030.  
  2031.         return(LocalConfig);
  2032.     }
  2033.     else
  2034.         return(NULL);
  2035. }
  2036.  
  2037. VOID
  2038. SaveConfig(struct Configuration *Src,struct Configuration *Dst)
  2039. {
  2040.     APTR From,To;
  2041.     LONG Type;
  2042.  
  2043.     for(Type = PREF_SERIAL ; Type < PREF_RATES ; Type++)
  2044.     {
  2045.         From    = GetConfigEntry(Src,Type);
  2046.         To        = GetConfigEntry(Dst,Type);
  2047.  
  2048.         if(From && To)
  2049.         {
  2050.             CopyMem(From,To,SizeTable[Type - PREF_SERIAL]);
  2051.  
  2052.             if(Type == PREF_SCREEN)
  2053.                 FixScreenPens(To);
  2054.         }
  2055.     }
  2056. }
  2057.  
  2058. VOID
  2059. SwapConfig(struct Configuration *Src,struct Configuration *Dst)
  2060. {
  2061.     APTR From,To;
  2062.     LONG Type;
  2063.  
  2064.     for(Type = PREF_SERIAL ; Type < PREF_RATES ; Type++)
  2065.     {
  2066.         From    = GetConfigEntry(Src,Type);
  2067.         To        = GetConfigEntry(Dst,Type);
  2068.  
  2069.         if(From && To)
  2070.             SwapMem(From,To,SizeTable[Type - PREF_SERIAL]);
  2071.     }
  2072. }
  2073.  
  2074. BOOL
  2075. SavePhonebook(STRPTR Name,PhonebookHandle *PhoneHandle)
  2076. {
  2077.     if(PhoneHandle->Phonebook && PhoneHandle->NumPhoneEntries > 0)
  2078.     {
  2079.         struct IFFHandle *Handle;
  2080.         LONG Error;
  2081.  
  2082.         if(!(Handle = CreatePhonebookFile(Name,PhoneHandle)))
  2083.             Error = IoErr();
  2084.         else
  2085.         {
  2086.             APTR TempBuffer;
  2087.  
  2088.             TempBuffer = NULL;
  2089.             Error = 0;
  2090.  
  2091.             if(PhoneHandle->PhonePasswordUsed)
  2092.             {
  2093.                 LONG Max = sizeof(PhoneHeader);
  2094.                 LONG Type;
  2095.  
  2096.                 for(Type = PREF_SERIAL ; Type < PREF_RATES ; Type++)
  2097.                 {
  2098.                     if(SizeTable[Type - PREF_SERIAL] > Max)
  2099.                         Max = SizeTable[Type - PREF_SERIAL];
  2100.                 }
  2101.  
  2102.                 if(!(TempBuffer = AllocVecPooled(Max,MEMF_ANY)))
  2103.                     Error = ERROR_NO_FREE_STORE;
  2104.             }
  2105.  
  2106.             if(!Error)
  2107.             {
  2108.                 if(!DumpPhonebookFile(Handle,TempBuffer,PhoneHandle))
  2109.                     Error = IoErr();
  2110.             }
  2111.  
  2112.             FreeVecPooled(TempBuffer);
  2113.  
  2114.             if(!ClosePhonebookFile(Handle))
  2115.             {
  2116.                 if(!Error)
  2117.                     Error = IoErr();
  2118.             }
  2119.  
  2120.             if(Error)
  2121.                 DeleteFile(Name);
  2122.         }
  2123.  
  2124.         if(Error)
  2125.         {
  2126.             SetIoErr(Error);
  2127.  
  2128.             return(FALSE);
  2129.         }
  2130.     }
  2131.  
  2132.     return(TRUE);
  2133. }
  2134.  
  2135.     /* LoadPhonebook(STRPTR Name):
  2136.      *
  2137.      *    Restore a phone book from a disk file.
  2138.      */
  2139.  
  2140. PhonebookHandle *
  2141. LoadPhonebook(STRPTR Name)
  2142. {
  2143.     struct PhoneEntry        **Phonebook;
  2144.     struct IFFHandle        *Handle;
  2145.     struct ContextNode        *Chunk;
  2146.     UBYTE                     ConfigChunkType;
  2147.     LONG                     Error;
  2148.     PhonebookHandle            *PhoneHandle;
  2149.     struct PhonebookGlobals     Globals;
  2150.     struct PhoneGroupHeader     GroupHeader;
  2151.     struct Configuration    *LocalConfig;
  2152.     LONG                     i;
  2153.     struct TermInfo             TermInfo;
  2154.     BOOL                     FirstChunk;
  2155.     BOOL                     CheckedChunk;
  2156.     BOOL                     GotID;
  2157.     LONG                     Index;
  2158.     LONG                     Size;
  2159.     UBYTE                     PasswordBuffer[MAX_PASSWORD_LENGTH];
  2160.     BOOL                     UsePhonePassword;
  2161.  
  2162.     PhoneHandle         = NULL;
  2163.     FirstChunk            = TRUE;
  2164.     CheckedChunk        = FALSE;
  2165.     GotID                = FALSE;
  2166.     Index                = 0;
  2167.     UsePhonePassword    = FALSE;
  2168.  
  2169.     if(Handle = OpenIFFStream(Name,MODE_OLDFILE))
  2170.     {
  2171.         if(!(Error = StopChunks(Handle,Stops,NUM_STOPS)))
  2172.         {
  2173.             while(!ParseIFF(Handle,IFFPARSE_SCAN))
  2174.             {
  2175.                 Chunk = CurrentChunk(Handle);
  2176.  
  2177.                     /* Is this the first chunk to be read? */
  2178.  
  2179.                 if(!CheckedChunk)
  2180.                 {
  2181.                     CheckedChunk = TRUE;
  2182.  
  2183.                         /* The first chunk must be a
  2184.                          * catalog chunk, or this would
  2185.                          * not be a proper phonebook file.
  2186.                          */
  2187.  
  2188.                     if(Chunk->cn_ID != ID_CAT)
  2189.                     {
  2190.                         Error = ERROR_OBJECT_WRONG_TYPE;
  2191.  
  2192.                         break;
  2193.                     }
  2194.                 }
  2195.  
  2196.                 switch(Chunk->cn_ID)
  2197.                 {
  2198.                     case ID_VERS:
  2199.  
  2200.                         memset(&TermInfo,0,sizeof(TermInfo));
  2201.  
  2202.                         if(ReadChunkBytes(Handle,&TermInfo,sizeof(struct TermInfo)) == sizeof(struct TermInfo))
  2203.                         {
  2204.                             if(TermInfo.Version != CONFIG_FILE_VERSION || (TermInfo.Version == CONFIG_FILE_VERSION && TermInfo.Revision > CONFIG_FILE_REVISION))
  2205.                             {
  2206.                                 if(TermInfo.Version == 2 && TermInfo.Revision == 4)
  2207.                                 {
  2208.                                     CloseIFFStream(Handle);
  2209.  
  2210.                                     return(LoadOldPhonebook(Name));
  2211.                                 }
  2212.                                 else
  2213.                                 {
  2214.                                     if(TermInfo.Version != 3)
  2215.                                         Error = ERROR_OBJECT_WRONG_TYPE;
  2216.                                 }
  2217.                             }
  2218.                         }
  2219.                         else
  2220.                             Error = IoErr();
  2221.  
  2222.                         break;
  2223.  
  2224.                     case ID_PSWD:
  2225.  
  2226.                         if(ReadChunkBytes(Handle,PasswordBuffer,MAX_PASSWORD_LENGTH) == MAX_PASSWORD_LENGTH)
  2227.                         {
  2228.                             BOOL AskPassword = TRUE;
  2229.  
  2230.                             if(GlobalPhoneHandle->PhonePasswordUsed)
  2231.                             {
  2232.                                 if(!memcmp(GlobalPhoneHandle->PhonePassword,PasswordBuffer,MAX_PASSWORD_LENGTH))
  2233.                                 {
  2234.                                     UsePhonePassword    = TRUE;
  2235.                                     AskPassword            = FALSE;
  2236.                                 }
  2237.                             }
  2238.  
  2239.                             if(AskPassword)
  2240.                             {
  2241.                                 UBYTE LocalBuffer[MAX_PASSWORD_LENGTH+1];
  2242.                                 BOOL Ok;
  2243.  
  2244.                                 memset(LocalBuffer,0,sizeof(LocalBuffer));
  2245.                                 Ok = FALSE;
  2246.  
  2247.                                 if(GetString(FALSE,TRUE,sizeof(LocalBuffer),LocaleString(MSG_PHONEPANEL_PLEASE_ENTER_PASSWORD_TXT),LocalBuffer))
  2248.                                 {
  2249.                                     UBYTE AnotherBuffer[MAX_PASSWORD_LENGTH];
  2250.  
  2251.                                     Encrypt(LocalBuffer,MAX_PASSWORD_LENGTH,AnotherBuffer,LocalBuffer,strlen(LocalBuffer));
  2252.  
  2253.                                     if(!memcmp(PasswordBuffer,AnotherBuffer,MAX_PASSWORD_LENGTH))
  2254.                                     {
  2255.                                         UsePhonePassword    = TRUE;
  2256.                                         Ok                    = TRUE;
  2257.                                     }
  2258.                                 }
  2259.  
  2260.                                 if(!Ok)
  2261.                                 {
  2262.                                     ShowRequest(Window,LocaleString(MSG_TERMPHONE_WRONG_PASSWORD_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Name);
  2263.  
  2264.                                     Error = ERROR_REQUIRED_ARG_MISSING;
  2265.                                 }
  2266.                             }
  2267.                         }
  2268.                         else
  2269.                             Error = IoErr();
  2270.  
  2271.                         break;
  2272.  
  2273.                     case ID_DIAL:
  2274.  
  2275.                         Size = MIN(sizeof(Globals),Chunk->cn_Size);
  2276.  
  2277.                         memset(&Globals,0,sizeof(Globals));
  2278.  
  2279.                         if(ReadChunkBytes(Handle,&Globals,Size) == Size)
  2280.                         {
  2281.                             if(Globals.Count > 0)
  2282.                             {
  2283.                                 if(!(PhoneHandle = CreatePhonebook(Globals.Count,TRUE)))
  2284.                                     Error = ERROR_NO_FREE_STORE;
  2285.                                 else
  2286.                                 {
  2287.                                     if(Size >= sizeof(PhonebookGlobals))
  2288.                                     {
  2289.                                         PhoneHandle->PhonebookID    = Globals.ID;
  2290.                                         PhoneHandle->DefaultGroup    = Globals.DefaultGroup;
  2291.                                         PhoneHandle->AutoDial        = Globals.AutoDial;
  2292.                                         PhoneHandle->AutoExit        = Globals.AutoExit;
  2293.  
  2294.                                         GotID = TRUE;
  2295.                                     }
  2296.                                     else
  2297.                                     {
  2298.                                         struct timeval Now;
  2299.  
  2300.                                         GetSysTime(&Now);
  2301.  
  2302.                                         PhoneHandle->PhonebookID    = Now.tv_secs;
  2303.                                         PhoneHandle->DefaultGroup    = 0;
  2304.                                         PhoneHandle->AutoDial        = FALSE;
  2305.                                         PhoneHandle->AutoExit        = FALSE;
  2306.  
  2307.                                         GotID = FALSE;
  2308.                                     }
  2309.  
  2310.                                     if(UsePhonePassword)
  2311.                                     {
  2312.                                         PhoneHandle->PhonePasswordUsed = TRUE;
  2313.                                         CopyMem(PasswordBuffer,PhoneHandle->PhonePassword,MAX_PASSWORD_LENGTH);
  2314.                                     }
  2315.  
  2316.                                     Phonebook = PhoneHandle->Phonebook;
  2317.                                 }
  2318.                             }
  2319.                         }
  2320.                         else
  2321.                             Error = IoErr();
  2322.  
  2323.                         break;
  2324.  
  2325.                     case ID_PHON:
  2326.  
  2327.                         Size = MIN(sizeof(PhoneHeader),Chunk->cn_Size);
  2328.  
  2329.                         if(FirstChunk)
  2330.                             FirstChunk = FALSE;
  2331.                         else
  2332.                             Index++;
  2333.  
  2334.                         memset(Phonebook[Index]->Header,0,sizeof(PhoneHeader));
  2335.  
  2336.                         if(ReadChunkBytes(Handle,Phonebook[Index]->Header,Size) == Size)
  2337.                         {
  2338.                             if(PhoneHandle->PhonePasswordUsed)
  2339.                                 Decrypt((UBYTE *)Phonebook[Index]->Header,Size,(UBYTE *)Phonebook[Index]->Header,PhoneHandle->PhonePassword,MAX_PASSWORD_LENGTH);
  2340.  
  2341.                             if(!GotID)
  2342.                                 Phonebook[Index]->Header->ID = PhoneHandle->PhonebookID++;
  2343.                         }
  2344.                         else
  2345.                             Error = IoErr();
  2346.  
  2347.                         break;
  2348.  
  2349.                         /* Mucho importante -- must follow the phonebook entries */
  2350.  
  2351.                     case ID_GRUP:
  2352.  
  2353.                         if(!Phonebook[PhoneHandle->NumPhoneEntries - 1])
  2354.                         {
  2355.                             Error = ERR_LOAD_ERROR;
  2356.                             break;
  2357.                         }
  2358.  
  2359.                         DB(kprintf("--> ID_GRUP\n"));
  2360.  
  2361.                         if(ReadChunkBytes(Handle,&GroupHeader,sizeof(GroupHeader)) == sizeof(GroupHeader))
  2362.                         {
  2363.                             PhoneGroupNode *GroupNode;
  2364.                             ULONG ID;
  2365.  
  2366.                             GroupNode = NULL;
  2367.  
  2368.                             DB(kprintf("group name |%s| entries %ld\n",GroupHeader.FullName,GroupHeader.Count));
  2369.  
  2370.                             for(i = 0 ; !Error && i < GroupHeader.Count ; i++)
  2371.                             {
  2372.                                 if(ReadChunkBytes(Handle,&ID,sizeof(ULONG)) == sizeof(ULONG))
  2373.                                 {
  2374.                                     LONG j;
  2375.  
  2376.                                     DB(kprintf("looking for 0x%08lx\n",ID));
  2377.  
  2378.                                     for(j = 0 ; j < PhoneHandle->NumPhoneEntries ; j++)
  2379.                                     {
  2380.                                         if(Phonebook[j]->Header->ID == ID)
  2381.                                         {
  2382.                                             DB(kprintf("found it |%s|\n",Phonebook[j]->Header->Name));
  2383.  
  2384.                                             if(!GroupNode)
  2385.                                                 GroupNode = CreatePhoneGroup(PhoneHandle,GroupHeader.FullName);
  2386.  
  2387.                                             if(!GroupNode)
  2388.                                             {
  2389.                                                 Error = ERROR_NO_FREE_STORE;
  2390.  
  2391.                                                 break;
  2392.                                             }
  2393.  
  2394.                                             if(!AddGroupEntry(GroupNode,Phonebook[j]))
  2395.                                             {
  2396.                                                 Error = ERROR_NO_FREE_STORE;
  2397.  
  2398.                                                 break;
  2399.                                             }
  2400.                                         }
  2401.                                     }
  2402.                                 }
  2403.                                 else
  2404.                                 {
  2405.                                     Error = IoErr();
  2406.  
  2407.                                     break;
  2408.                                 }
  2409.                             }
  2410.                         }
  2411.                         else
  2412.                             Error = IoErr();
  2413.  
  2414.                         break;
  2415.  
  2416.                     /* Special treatment for obsolete "FILE" chunk */
  2417.  
  2418.                     case ID_FILE:
  2419.  
  2420.                         LocalConfig = Phonebook[Index]->Config;
  2421.  
  2422.                         for(i = PREF_TRANSLATIONFILENAME ; !Error && i < PREF_RATES ; i++)
  2423.                         {
  2424.                             if(!CreateConfigEntry(LocalConfig,i))
  2425.                                 Error = ERROR_NO_FREE_STORE;
  2426.                         }
  2427.  
  2428.                         if(!Error)
  2429.                         {
  2430.                             strcpy(LocalConfig->TranslationFileName,    LocalConfig->FileConfig->TranslationFileName);
  2431.                             strcpy(LocalConfig->MacroFileName,        LocalConfig->FileConfig->MacroFileName);
  2432.                             strcpy(LocalConfig->CursorFileName,        LocalConfig->FileConfig->CursorFileName);
  2433.                             strcpy(LocalConfig->FastMacroFileName,    LocalConfig->FileConfig->FastMacroFileName);
  2434.  
  2435.                             DeleteConfigEntry(LocalConfig,PREF_FILE);
  2436.                         }
  2437.  
  2438.                         break;
  2439.  
  2440.                     case ID_DATE:
  2441.  
  2442.                         if(!Phonebook[Index]->Header->NoRates)
  2443.                         {
  2444.                             LONG Count = (Chunk->cn_Size - sizeof(struct TimeDateHeader)) / sizeof(struct TimeDateOld);
  2445.                             struct TimeDateNode *TimeDateNode;
  2446.  
  2447.                             if(TimeDateNode = CreateTimeDateNode(-1,-1,"",Count))
  2448.                             {
  2449.                                 struct TimeDateOld *Old;
  2450.  
  2451.                                 if(Old = (struct TimeDateOld *)AllocVecPooled(sizeof(struct TimeDateOld) * Count,MEMF_ANY))
  2452.                                 {
  2453.                                     if(ReadChunkBytes(Handle,&TimeDateNode->Header,sizeof(struct TimeDateHeader)) == sizeof(struct TimeDateHeader))
  2454.                                     {
  2455.                                         if(ReadChunkRecords(Handle,Old,sizeof(struct TimeDateOld),Count) == Count)
  2456.                                         {
  2457.                                             for(i = 0 ; i < Count ; i++)
  2458.                                                 ConvertTimeDate(&Old[i],&TimeDateNode->Table[i]);
  2459.  
  2460.                                             AdaptTimeDateNode(TimeDateNode);
  2461.  
  2462.                                             AddTail((struct List *)&Phonebook[Index]->TimeDateList,&TimeDateNode->Node);
  2463.  
  2464.                                             TimeDateNode = NULL;
  2465.                                         }
  2466.                                         else
  2467.                                             Error = IoErr();
  2468.                                     }
  2469.                                     else
  2470.                                         Error = IoErr();
  2471.  
  2472.                                     FreeVecPooled(Old);
  2473.                                 }
  2474.                                 else
  2475.                                     Error = ERROR_NO_FREE_STORE;
  2476.  
  2477.                                 FreeTimeDateNode(TimeDateNode);
  2478.                             }
  2479.                             else
  2480.                                 Error = ERROR_NO_FREE_STORE;
  2481.                         }
  2482.  
  2483.                         break;
  2484.  
  2485.                     case ID_DAT2:
  2486.  
  2487.                         if(!Phonebook[Index]->Header->NoRates)
  2488.                         {
  2489.                             LONG Count = (Chunk->cn_Size - sizeof(struct TimeDateHeader)) / sizeof(struct TimeDate);
  2490.                             struct TimeDateNode *TimeDateNode;
  2491.  
  2492.                             if(TimeDateNode = CreateTimeDateNode(-1,-1,"",Count))
  2493.                             {
  2494.                                 if(ReadChunkBytes(Handle,&TimeDateNode->Header,sizeof(struct TimeDateHeader)) == sizeof(struct TimeDateHeader))
  2495.                                 {
  2496.                                     if(ReadChunkRecords(Handle,TimeDateNode->Table,sizeof(struct TimeDate),Count) == Count)
  2497.                                     {
  2498.                                         AdaptTimeDateNode(TimeDateNode);
  2499.  
  2500.                                         AddTail((struct List *)&Phonebook[Index]->TimeDateList,&TimeDateNode->Node);
  2501.  
  2502.                                         TimeDateNode = NULL;
  2503.                                     }
  2504.                                     else
  2505.                                         Error = IoErr();
  2506.                                 }
  2507.                                 else
  2508.                                     Error = IoErr();
  2509.  
  2510.                                 FreeTimeDateNode(TimeDateNode);
  2511.                             }
  2512.                             else
  2513.                                 Error = IoErr();
  2514.                         }
  2515.  
  2516.                         break;
  2517.  
  2518.                     default:
  2519.  
  2520.                         if(ConfigChunkType = IsConfigChunk(Chunk->cn_ID))
  2521.                         {
  2522.                             if(ReadConfigChunk(Handle,Phonebook[Index]->Config,ConfigChunkType,Chunk->cn_Size,PhoneHandle->PhonePasswordUsed ? PhoneHandle->PhonePassword : NULL))
  2523.                                 FixOldConfig(Phonebook[Index]->Config,ConfigChunkType,TRUE,TermInfo.Version,TermInfo.Revision);
  2524.                             else
  2525.                                 Error = IoErr();
  2526.                         }
  2527.  
  2528.                         break;
  2529.                 }
  2530.  
  2531.                 if(Error)
  2532.                     break;
  2533.             }
  2534.  
  2535.             if(!Error && PhoneHandle)
  2536.             {
  2537.                 if(!Phonebook[PhoneHandle->NumPhoneEntries - 1])
  2538.                     Error = ERR_LOAD_ERROR;
  2539.             }
  2540.  
  2541.             if(!Error)
  2542.             {
  2543.                 for(i = 0 ; i < PhoneHandle->NumPhoneEntries ; i++)
  2544.                 {
  2545.                     FinalFix(Phonebook[i]->Config,TRUE,TermInfo.Version,TermInfo.Revision);
  2546.                     StripGlobals(Phonebook[i]->Config);
  2547.                 }
  2548.             }
  2549.         }
  2550.  
  2551.         CloseIFFStream(Handle);
  2552.     }
  2553.     else
  2554.         Error = IoErr();
  2555.  
  2556.     if(Error)
  2557.     {
  2558.         if(PhoneHandle)
  2559.             DeletePhonebook(PhoneHandle);
  2560.  
  2561.         SetIoErr(Error);
  2562.  
  2563.         return(NULL);
  2564.     }
  2565.     else
  2566.         return(PhoneHandle);
  2567. }
  2568.  
  2569.     /* WriteConfig(STRPTR Name,struct Configuration *LocalConfig):
  2570.      *
  2571.      *    Write the configuration to a file, very much like
  2572.      *    WriteIFFData().
  2573.      */
  2574.  
  2575. BOOL
  2576. WriteConfig(STRPTR Name,struct Configuration *LocalConfig)
  2577. {
  2578.     struct IFFHandle *Handle;
  2579.     LONG Error;
  2580.  
  2581.         /* Allocate a handle. */
  2582.  
  2583.     if(Handle = OpenIFFStream(Name,MODE_NEWFILE))
  2584.     {
  2585.             /* Push outmost chunk onto stack. */
  2586.  
  2587.         if(!(Error = PushChunk(Handle,ID_TERM,ID_FORM,IFFSIZE_UNKNOWN)))
  2588.         {
  2589.                 /* Add a version identifier. */
  2590.  
  2591.             if(!(Error = PushChunk(Handle,0,ID_VERS,IFFSIZE_UNKNOWN)))
  2592.             {
  2593.                 struct TermInfo TermInfo;
  2594.  
  2595.                 TermInfo.Version    = CONFIG_FILE_VERSION;
  2596.                 TermInfo.Revision    = CONFIG_FILE_REVISION;
  2597.  
  2598.                     /* Update the other configuration pointer as well. */
  2599.  
  2600.                 LocalConfig->SerialConfig->LastVersionSaved        = TermVersion;
  2601.                 LocalConfig->SerialConfig->LastRevisionSaved    = TermRevision;
  2602.  
  2603.                     /* Write the version data. */
  2604.  
  2605.                 if(WriteChunkBytes(Handle,&TermInfo,sizeof(struct TermInfo)) != sizeof(struct TermInfo))
  2606.                     Error = IoErr();
  2607.                 else
  2608.                     Error = PopChunk(Handle);
  2609.             }
  2610.  
  2611.             if(!Error)
  2612.             {
  2613.                 if(!WriteConfigChunks(Handle,LocalConfig,NULL,NULL))
  2614.                     Error = IoErr();
  2615.             }
  2616.  
  2617.             if(!Error)
  2618.             {
  2619.                 LONG i;
  2620.  
  2621.                 for(i = 0 ; !Error && WindowInfoTable[i].ID != -1 ; i++)
  2622.                 {
  2623.                     if(!(Error = PushChunk(Handle,0,ID_WINF,sizeof(struct WindowInfo))))
  2624.                     {
  2625.                         if(WriteChunkBytes(Handle,&WindowInfoTable[i],sizeof(struct WindowInfo)) != sizeof(struct WindowInfo))
  2626.                             Error = IoErr();
  2627.                         else
  2628.                             Error = PopChunk(Handle);
  2629.                     }
  2630.                 }
  2631.             }
  2632.  
  2633.                 /* Seems that we're finished, now try to pop the FORM chunk
  2634.                  * and return.
  2635.                  */
  2636.  
  2637.             if(!Error)
  2638.                 Error = PopChunk(Handle);
  2639.         }
  2640.  
  2641.             /* Close the handle (flush any pending data). */
  2642.  
  2643.         CloseIFFStream(Handle);
  2644.     }
  2645.     else
  2646.         Error = IoErr();
  2647.  
  2648.     if(Error)
  2649.     {
  2650.         DeleteFile(Name);
  2651.         SetIoErr(Error);
  2652.  
  2653.         return(FALSE);
  2654.     }
  2655.     else
  2656.     {
  2657.         AddProtection(Name,FIBF_EXECUTE);
  2658.  
  2659.         return(TRUE);
  2660.     }
  2661. }
  2662.  
  2663.     /* ReadConfig(STRPTR Name,struct Configuration *LocalConfig):
  2664.      *
  2665.      *    Read the configuration file, very much the same as ReadIFFData().
  2666.      */
  2667.  
  2668. BOOL
  2669. ReadConfig(STRPTR Name,struct Configuration *LocalConfig)
  2670. {
  2671.     struct IFFHandle *Handle;
  2672.     LONG Error;
  2673.  
  2674.     if(Handle = OpenIFFStream(Name,MODE_OLDFILE))
  2675.     {
  2676.         if(!(Error = StopChunks(Handle,Stops,NUM_STOPS)))
  2677.         {
  2678.             struct WindowInfo WindowInfo;
  2679.             struct ContextNode *Chunk;
  2680.             struct TermInfo TermInfo;
  2681.             LONG ConfigChunkType;
  2682.             LONG Type;
  2683.  
  2684.             memset(&TermInfo,0,sizeof(TermInfo));
  2685.  
  2686.             while(!ParseIFF(Handle,IFFPARSE_SCAN))
  2687.             {
  2688.                 Chunk = CurrentChunk(Handle);
  2689.  
  2690.                 switch(Chunk->cn_ID)
  2691.                 {
  2692.                         /* Oops! Someone is trying to
  2693.                          * use the phone book file as
  2694.                          * a configuration file.
  2695.                          */
  2696.  
  2697.                     case ID_CAT:
  2698.  
  2699.                         Error = ERROR_OBJECT_WRONG_TYPE;
  2700.  
  2701.                         break;
  2702.  
  2703.                         /* File version information. */
  2704.  
  2705.                     case ID_VERS:
  2706.  
  2707.                         if(ReadChunkBytes(Handle,&TermInfo,sizeof(struct TermInfo)) != sizeof(struct TermInfo))
  2708.                             Error = IoErr();
  2709.                         else
  2710.                         {
  2711.                             if(TermInfo.Version != CONFIG_FILE_VERSION || (TermInfo.Version == CONFIG_FILE_VERSION && TermInfo.Revision > CONFIG_FILE_REVISION))
  2712.                             {
  2713.                                     /* Old file format (v2.4); stop here and pass
  2714.                                      * control to the compatibility code.
  2715.                                      */
  2716.  
  2717.                                 if(TermInfo.Version == 2 && TermInfo.Revision == 4)
  2718.                                 {
  2719.                                     CloseIFFStream(Handle);
  2720.  
  2721.                                     return(ReadOldConfig(Name,LocalConfig));
  2722.                                 }
  2723.                                 else
  2724.                                 {
  2725.                                     if(TermInfo.Version != 3)
  2726.                                         Error = ERROR_OBJECT_WRONG_TYPE;
  2727.                                 }
  2728.                             }
  2729.                         }
  2730.  
  2731.                         break;
  2732.  
  2733.                         /* Window placement information. */
  2734.  
  2735.                     case ID_WINF:
  2736.  
  2737.                         if(ReadChunkBytes(Handle,&WindowInfo,sizeof(struct WindowInfo)) != sizeof(struct WindowInfo))
  2738.                             Error = IoErr();
  2739.                         else
  2740.                             ReplaceWindowInfo(&WindowInfo);
  2741.  
  2742.                         break;
  2743.  
  2744.                         /* Special treatment for obsolete "FILE" chunk */
  2745.  
  2746.                     case ID_FILE:
  2747.  
  2748.                         for(Type = PREF_TRANSLATIONFILENAME ; !Error && Type < PREF_RATES ; Type++)
  2749.                         {
  2750.                             if(!CreateConfigEntry(LocalConfig,Type))
  2751.                                 Error = ERROR_NO_FREE_STORE;
  2752.                         }
  2753.  
  2754.                         if(!Error)
  2755.                         {
  2756.                             strcpy(LocalConfig->TranslationFileName,    LocalConfig->FileConfig->TranslationFileName);
  2757.                             strcpy(LocalConfig->MacroFileName,            LocalConfig->FileConfig->MacroFileName);
  2758.                             strcpy(LocalConfig->CursorFileName,            LocalConfig->FileConfig->CursorFileName);
  2759.                             strcpy(LocalConfig->FastMacroFileName,        LocalConfig->FileConfig->FastMacroFileName);
  2760.  
  2761.                             DeleteConfigEntry(LocalConfig,PREF_FILE);
  2762.                         }
  2763.  
  2764.                         break;
  2765.  
  2766.                         /* Any other configuration file chunk. */
  2767.  
  2768.                     default:
  2769.  
  2770.                         if(ConfigChunkType = IsConfigChunk(Chunk->cn_ID))
  2771.                         {
  2772.                             if(!ReadConfigChunk(Handle,LocalConfig,ConfigChunkType,Chunk->cn_Size,NULL))
  2773.                                 Error = IoErr();
  2774.                             else
  2775.                                 FixOldConfig(LocalConfig,ConfigChunkType,FALSE,TermInfo.Version,TermInfo.Revision);
  2776.                         }
  2777.  
  2778.                         break;
  2779.                 }
  2780.  
  2781.                     /* Stop in case of error. */
  2782.  
  2783.                 if(Error)
  2784.                     break;
  2785.             }
  2786.  
  2787.                 /* Patch up configuration file information if necessary. */
  2788.  
  2789.             if(!Error)
  2790.                 FinalFix(LocalConfig,FALSE,TermInfo.Version,TermInfo.Revision);
  2791.         }
  2792.  
  2793.         CloseIFFStream(Handle);
  2794.     }
  2795.     else
  2796.         Error = IoErr();
  2797.  
  2798.     if(Error)
  2799.     {
  2800.         SetIoErr(Error);
  2801.  
  2802.         return(FALSE);
  2803.     }
  2804.     else
  2805.         return(TRUE);
  2806. }
  2807.  
  2808. /*****************************************************************************/
  2809.  
  2810.     /* ResetHotkeys(struct Hotkeys *Hotkeys):
  2811.      *
  2812.      *    Reset hotkey assignments to defaults.
  2813.      */
  2814.  
  2815. VOID
  2816. ResetHotkeys(struct Hotkeys *Hotkeys)
  2817. {
  2818.     strcpy(Hotkeys->termScreenToFront,        "lshift rshift return");
  2819.     strcpy(Hotkeys->BufferScreenToFront,    "control rshift return");
  2820.     strcpy(Hotkeys->SkipDialEntry,            "control lshift rshift return");
  2821.     strcpy(Hotkeys->AbortARexx,                "lshift rshift escape");
  2822.  
  2823.     Hotkeys->CommodityPriority    = 0;
  2824.     Hotkeys->HotkeysEnabled        = TRUE;
  2825. }
  2826.  
  2827.     /* ResetSpeechConfig(struct SpeechConfig *SpeechConfig):
  2828.      *
  2829.      *    Reset speech configuration to defaults.
  2830.      */
  2831.  
  2832. VOID
  2833. ResetSpeechConfig(struct SpeechConfig *SpeechConfig)
  2834. {
  2835.     SpeechConfig->Rate        = DEFRATE;
  2836.     SpeechConfig->Pitch        = DEFPITCH;
  2837.     SpeechConfig->Frequency    = DEFFREQ;
  2838.     SpeechConfig->Volume    = DEFVOL;
  2839.     SpeechConfig->Sex        = DEFSEX;
  2840.     SpeechConfig->Enabled    = FALSE;
  2841. }
  2842.  
  2843.     /* ResetCursorKeys(struct CursorKeys *Keys):
  2844.      *
  2845.      *    Reset cursor key assignments to defaults.
  2846.      */
  2847.  
  2848. VOID
  2849. ResetCursorKeys(struct CursorKeys *Keys)
  2850. {
  2851.     STATIC STRPTR Defaults[4] =
  2852.     {
  2853.         "\\e[A",
  2854.         "\\e[B",
  2855.         "\\e[C",
  2856.         "\\e[D"
  2857.     };
  2858.  
  2859.     LONG i,j;
  2860.  
  2861.     for(i = 0 ; i < 4 ; i++)
  2862.     {
  2863.         for(j = 0 ; j < 4 ; j++)
  2864.             strcpy(Keys->Keys[j][i],Defaults[i]);
  2865.     }
  2866. }
  2867.  
  2868.     /* ResetSound(struct SoundConfig *SoundConfig):
  2869.      *
  2870.      *    Reset the sound settings to defaults.
  2871.      */
  2872.  
  2873. VOID
  2874. ResetSound(struct SoundConfig *SoundConfig)
  2875. {
  2876.     memset(SoundConfig,0,sizeof(struct SoundConfig));
  2877.  
  2878.     SoundConfig->Volume = 100;
  2879.  
  2880.     strcpy(SoundConfig->BellFile,Config->TerminalConfig->BeepFileName);
  2881. }
  2882.  
  2883.     /* ResetMacroKeys(struct MacroKeys *Keys):
  2884.      *
  2885.      *    Reset the macro key assignments to defaults.
  2886.      */
  2887.  
  2888. VOID
  2889. ResetMacroKeys(struct MacroKeys *Keys)
  2890. {
  2891.     STATIC STRPTR FunctionKeyCodes[4] =
  2892.     {
  2893.         "\\eOP",
  2894.         "\\eOQ",
  2895.         "\\eOR",
  2896.         "\\eOS"
  2897.     };
  2898.  
  2899.     LONG i;
  2900.  
  2901.     memset(Keys,0,sizeof(struct MacroKeys));
  2902.  
  2903.     for(i = 0 ; i < 4 ; i++)
  2904.         strcpy(Keys->Keys[1][i],FunctionKeyCodes[i]);
  2905. }
  2906.  
  2907.     /* LoadMacros(STRPTR Name,struct MacroKeys *Keys):
  2908.      *
  2909.      *    Load the keyboard macros from a file.
  2910.      */
  2911.  
  2912. BOOL
  2913. LoadMacros(STRPTR Name,struct MacroKeys *Keys)
  2914. {
  2915.     struct StoredProperty *Prop;
  2916.     struct TermInfo *TermInfo;
  2917.     struct IFFHandle *Handle;
  2918.     LONG Error;
  2919.  
  2920.     if(Handle = OpenIFFStream(Name,MODE_OLDFILE))
  2921.     {
  2922.             /* Collect version number ID if
  2923.              * available.
  2924.              */
  2925.  
  2926.         if(!(Error = PropChunks(Handle,(LONG *)VersionProps,1)))
  2927.         {
  2928.                 /* The following line tells iffparse to stop at the
  2929.                  * very beginning of a `Type' chunk contained in a
  2930.                  * `TERM' FORM chunk.
  2931.                  */
  2932.  
  2933.             if(!(Error = StopChunk(Handle,ID_TERM,ID_KEYS)))
  2934.             {
  2935.                     /* Parse the file... */
  2936.  
  2937.                 if(!ParseIFF(Handle,IFFPARSE_SCAN))
  2938.                 {
  2939.                         /* Did we get a version ID? */
  2940.  
  2941.                     if(Prop = FindProp(Handle,ID_TERM,ID_VERS))
  2942.                     {
  2943.                         TermInfo = (struct TermInfo *)Prop->sp_Data;
  2944.  
  2945.                             /* Is it the file format we are able
  2946.                              * to read?
  2947.                              */
  2948.  
  2949.                         if((TermInfo->Version > CONFIG_FILE_VERSION) || (TermInfo->Version == CONFIG_FILE_VERSION && TermInfo->Revision > CONFIG_FILE_REVISION) || (TermInfo->Version == 1 && TermInfo->Revision < 6))
  2950.                         {
  2951.                                 /* Probably an older revision. */
  2952.  
  2953.                             if(TermInfo->Version == 1 && TermInfo->Revision < 6)
  2954.                             {
  2955.                                 memset(Keys,0,sizeof(struct MacroKeys));
  2956.  
  2957.                                 if(ReadChunkBytes(Handle,Keys,10 * 256) != 10 * 256)
  2958.                                     Error = IoErr();
  2959.                             }
  2960.                             else
  2961.                                 Error = ERR_OUTDATED;
  2962.                         }
  2963.                         else
  2964.                         {
  2965.                             /* The file read pointer is positioned
  2966.                              * just in front of the first data
  2967.                              * to be read, so let's don't disappoint
  2968.                              * iffparse and read it.
  2969.                              */
  2970.  
  2971.                             if(ReadChunkBytes(Handle,Keys,sizeof(struct MacroKeys)) != sizeof(struct MacroKeys))
  2972.                                 Error = IoErr();
  2973.                         }
  2974.                     }
  2975.                     else
  2976.                     {
  2977.                             /* File was created by WriteIFFData previous
  2978.                              * to revision 1.4.
  2979.                              */
  2980.  
  2981.                         memset(Keys,0,sizeof(struct MacroKeys));
  2982.  
  2983.                         if(ReadChunkBytes(Handle,Keys,10 * 256) != 10 * 256)
  2984.                             Error = IoErr();
  2985.                     }
  2986.                 }
  2987.             }
  2988.         }
  2989.  
  2990.         CloseIFFStream(Handle);
  2991.     }
  2992.     else
  2993.         Error = IoErr();
  2994.  
  2995.     if(!Error)
  2996.         return(TRUE);
  2997.     else
  2998.     {
  2999.         SetIoErr(Error);
  3000.  
  3001.         return(FALSE);
  3002.     }
  3003. }
  3004.  
  3005. /*****************************************************************************/
  3006.  
  3007.     /* WriteIFFData(STRPTR Name,APTR Data,LONG Size,ULONG Type):
  3008.      *
  3009.      *    Write data to an IFF file (via iffparse.library).
  3010.      */
  3011.  
  3012. BOOL
  3013. WriteIFFData(STRPTR Name,APTR Data,LONG Size,ULONG Type)
  3014. {
  3015.     struct IFFHandle *Handle;
  3016.     LONG Error;
  3017.  
  3018.         /* Allocate a handle. */
  3019.  
  3020.     if(!(Handle = OpenIFFStream(Name,MODE_NEWFILE)))
  3021.         Error = IoErr();
  3022.     else
  3023.     {
  3024.             /* Push outmost chunk onto stack. */
  3025.  
  3026.         if(!(Error = PushChunk(Handle,ID_TERM,ID_FORM,IFFSIZE_UNKNOWN)))
  3027.         {
  3028.                 /* Add a version identifier. */
  3029.  
  3030.             if(!(Error = PushChunk(Handle,0,ID_VERS,IFFSIZE_UNKNOWN)))
  3031.             {
  3032.                 struct TermInfo TermInfo;
  3033.  
  3034.                 TermInfo.Version    = CONFIG_FILE_VERSION;
  3035.                 TermInfo.Revision    = CONFIG_FILE_REVISION;
  3036.  
  3037.                     /* Write the version data. */
  3038.  
  3039.                 if(WriteChunkBytes(Handle,&TermInfo,sizeof(struct TermInfo)) != sizeof(struct TermInfo))
  3040.                     Error = IoErr();
  3041.                 else
  3042.                     Error = PopChunk(Handle);
  3043.             }
  3044.  
  3045.                 /* Push the real data chunk on the stack. */
  3046.  
  3047.             if(!Error)
  3048.             {
  3049.                 if(!(Error = PushChunk(Handle,0,Type,Size)))
  3050.                 {
  3051.                         /* Write the data. */
  3052.  
  3053.                     if(WriteChunkBytes(Handle,Data,Size) != Size)
  3054.                         Error = IoErr();
  3055.                     else
  3056.                         Error = PopChunk(Handle);
  3057.                 }
  3058.             }
  3059.  
  3060.                 /* Seems that we're done, now try to pop the FORM chunk
  3061.                  * and return.
  3062.                  */
  3063.  
  3064.             if(!Error)
  3065.                 Error = PopChunk(Handle);
  3066.         }
  3067.  
  3068.         CloseIFFStream(Handle);
  3069.     }
  3070.  
  3071.     if(!Error)
  3072.     {
  3073.         AddProtection(Name,FIBF_EXECUTE);
  3074.  
  3075.         return(TRUE);
  3076.     }
  3077.     else
  3078.     {
  3079.         DeleteFile(Name);
  3080.         SetIoErr(Error);
  3081.  
  3082.         return(FALSE);
  3083.     }
  3084. }
  3085.  
  3086.     /* ReadIFFData(STRPTR Name,APTR Data,LONG Size,ULONG Type):
  3087.      *
  3088.      *    Read data from a `TERM' FORM chunk contained in an IFF file.
  3089.      */
  3090.  
  3091. BOOL
  3092. ReadIFFData(STRPTR Name,APTR Data,LONG Size,ULONG Type)
  3093. {
  3094.     struct IFFHandle *Handle;
  3095.     LONG Error;
  3096.  
  3097.     if(!(Handle = OpenIFFStream(Name,MODE_OLDFILE)))
  3098.         Error = IoErr();
  3099.     else
  3100.     {
  3101.             /* Collect version number ID if
  3102.              * available.
  3103.              */
  3104.  
  3105.         if(!(Error = PropChunks(Handle,(LONG *)VersionProps,1)))
  3106.         {
  3107.                 /* The following line tells iffparse to stop at the
  3108.                  * very beginning of a `Type' chunk contained in a
  3109.                  * `TERM' FORM chunk.
  3110.                  */
  3111.  
  3112.             if(!(Error = StopChunk(Handle,ID_TERM,Type)))
  3113.             {
  3114.                     /* Parse the file... */
  3115.  
  3116.                 if(!ParseIFF(Handle,IFFPARSE_SCAN))
  3117.                 {
  3118.                     struct StoredProperty *Prop;
  3119.  
  3120.                         /* Did we get a version ID? */
  3121.  
  3122.                     if(!(Prop = FindProp(Handle,ID_TERM,ID_VERS)))
  3123.                         Error = ERR_OUTDATED;
  3124.                     else
  3125.                     {
  3126.                         struct TermInfo *TermInfo;
  3127.  
  3128.                         TermInfo = (struct TermInfo *)Prop->sp_Data;
  3129.  
  3130.                             /* Is it the file format we are able
  3131.                              * to read?
  3132.                              */
  3133.  
  3134.                         if((TermInfo->Version > CONFIG_FILE_VERSION) || (TermInfo->Version == CONFIG_FILE_VERSION && TermInfo->Revision > CONFIG_FILE_REVISION) || (TermInfo->Version == 1 && TermInfo->Revision < 6))
  3135.                             Error = ERR_OUTDATED;
  3136.                         else
  3137.                         {
  3138.                             struct ContextNode *Chunk = CurrentChunk(Handle);
  3139.  
  3140.                             if(Chunk->cn_Size < Size)
  3141.                                 Size = Chunk->cn_Size;
  3142.  
  3143.                                 /* The file read pointer is positioned
  3144.                                  * just in front of the first data
  3145.                                  * to be read, so let's don't disappoint
  3146.                                  * iffparse and read it.
  3147.                                  */
  3148.  
  3149.                             if(ReadChunkBytes(Handle,Data,Size) != Size)
  3150.                                 Error = IoErr();
  3151.                         }
  3152.                     }
  3153.                 }
  3154.             }
  3155.         }
  3156.  
  3157.         CloseIFFStream(Handle);
  3158.     }
  3159.  
  3160.     if(!Error)
  3161.         return(TRUE);
  3162.     else
  3163.     {
  3164.         SetIoErr(Error);
  3165.         return(FALSE);
  3166.     }
  3167. }
  3168.